jaml-ui 0.21.2 → 0.21.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/DESIGN.md +36 -6
- package/dist/components/JamlAnalyzerFullscreen.d.ts +1 -1
- package/dist/components/JamlAnalyzerFullscreen.js +5 -81
- package/dist/components/JamlCurator.js +1 -1
- package/dist/components/JamlSpeedometer.d.ts +7 -2
- package/dist/components/JamlSpeedometer.js +8 -15
- package/dist/components/jamlMap/JamlMapEditor.js +42 -38
- package/dist/components/jamlMap/JokerPicker.js +2 -2
- package/dist/components/jamlMap/MysterySlot.js +4 -4
- package/dist/hooks/useSearch.d.ts +2 -1
- package/dist/hooks/useSearch.js +111 -8
- package/dist/lib/SpriteMapper.d.ts +10 -0
- package/dist/lib/SpriteMapper.js +48 -0
- package/dist/lib/cardParser.d.ts +8 -0
- package/dist/lib/cardParser.js +65 -0
- package/dist/lib/classes/BuyMetaData.d.ts +11 -0
- package/dist/lib/classes/BuyMetaData.js +1 -0
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.js +15 -0
- package/dist/lib/const.d.ts +61 -0
- package/dist/lib/const.js +521 -0
- package/dist/lib/data/constants.d.ts +11 -0
- package/dist/lib/data/constants.js +17 -0
- package/dist/lib/hooks/useDragScroll.d.ts +4 -0
- package/dist/lib/hooks/useDragScroll.js +48 -0
- package/dist/lib/hooks/useJamlFilter.d.ts +48 -0
- package/dist/lib/hooks/useJamlFilter.js +219 -0
- package/dist/lib/hooks/useSeedAnalyzer.d.ts +6 -0
- package/dist/lib/hooks/useSeedAnalyzer.js +48 -0
- package/dist/lib/jaml/jamlCompletion.d.ts +12 -0
- package/dist/lib/jaml/jamlCompletion.js +13 -0
- package/dist/lib/jaml/jamlData.d.ts +3 -0
- package/dist/lib/jaml/jamlData.js +8 -0
- package/dist/lib/jaml/jamlObjectives.d.ts +13 -0
- package/dist/lib/jaml/jamlObjectives.js +97 -0
- package/dist/lib/jaml/jamlParser.d.ts +14 -0
- package/dist/lib/jaml/jamlParser.js +47 -0
- package/dist/lib/jaml/jamlPresets.d.ts +8 -0
- package/dist/lib/jaml/jamlPresets.js +61 -0
- package/dist/lib/jaml/jamlSchema.d.ts +54 -0
- package/dist/lib/jaml/jamlSchema.js +91 -0
- package/dist/lib/parseDailyRitual.d.ts +45 -0
- package/dist/lib/parseDailyRitual.js +69 -0
- package/dist/lib/tts/getRevealPos.d.ts +5 -0
- package/dist/lib/tts/getRevealPos.js +16 -0
- package/dist/lib/tts/splitTtsDisplay.d.ts +19 -0
- package/dist/lib/tts/splitTtsDisplay.js +35 -0
- package/dist/lib/types.d.ts +121 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/dist/ui/JimboIconButton.d.ts +10 -0
- package/dist/ui/JimboIconButton.js +28 -0
- package/dist/ui/JimboInputModal.d.ts +13 -0
- package/dist/ui/JimboInputModal.js +60 -0
- package/dist/ui/JimboSelect.d.ts +18 -0
- package/dist/ui/JimboSelect.js +43 -0
- package/dist/ui/PanelSplitter.d.ts +7 -0
- package/dist/ui/PanelSplitter.js +76 -0
- package/dist/ui/ide/AgnosticSeedCard.d.ts +19 -0
- package/dist/ui/ide/AgnosticSeedCard.js +48 -0
- package/dist/ui/ide/DeckSprite.d.ts +1 -0
- package/dist/ui/ide/DeckSprite.js +2 -0
- package/dist/ui/ide/JamlBuilder.d.ts +1 -0
- package/dist/ui/ide/JamlBuilder.js +112 -0
- package/dist/ui/ide/JamlEditor.d.ts +7 -0
- package/dist/ui/ide/JamlEditor.js +496 -0
- package/dist/ui/ide/JamlEditorMonaco.d.ts +8 -0
- package/dist/ui/ide/JamlEditorMonaco.js +78 -0
- package/dist/ui/ide/WasmStatus.d.ts +1 -0
- package/dist/ui/ide/WasmStatus.js +42 -0
- package/dist/ui/jimbo.css +336 -31
- package/dist/ui/jimboApp.d.ts +12 -0
- package/dist/ui/jimboApp.js +15 -0
- package/dist/ui/jimboInfoCard.d.ts +31 -0
- package/dist/ui/jimboInfoCard.js +26 -0
- package/dist/ui/jimboInset.d.ts +9 -0
- package/dist/ui/jimboInset.js +9 -0
- package/dist/ui/jimboSectionHeader.d.ts +11 -0
- package/dist/ui/jimboSectionHeader.js +9 -0
- package/dist/ui/jimboStatGrid.d.ts +13 -0
- package/dist/ui/jimboStatGrid.js +9 -0
- package/dist/ui/jimboWordmark.d.ts +10 -0
- package/dist/ui/jimboWordmark.js +9 -0
- package/dist/ui/mascot/JammySpeechBox.d.ts +9 -0
- package/dist/ui/mascot/JammySpeechBox.js +30 -0
- package/dist/ui/mascot/SeedMascot.d.ts +37 -0
- package/dist/ui/mascot/SeedMascot.js +17 -0
- package/dist/ui/mascot/index.d.ts +3 -0
- package/dist/ui/mascot/index.js +3 -0
- package/dist/ui/mascot/menuConfig.d.ts +102 -0
- package/dist/ui/mascot/menuConfig.js +12 -0
- package/dist/ui/panel.d.ts +1 -1
- package/dist/ui/panel.js +3 -21
- package/dist/ui/radial/RadialBadge.d.ts +17 -0
- package/dist/ui/radial/RadialBadge.js +43 -0
- package/dist/ui/radial/RadialBreadcrumb.d.ts +12 -0
- package/dist/ui/radial/RadialBreadcrumb.js +18 -0
- package/dist/ui/radial/RadialButton.d.ts +61 -0
- package/dist/ui/radial/RadialButton.js +102 -0
- package/dist/ui/radial/RadialMenu.d.ts +38 -0
- package/dist/ui/radial/RadialMenu.js +168 -0
- package/dist/ui/radial/RadialPill.d.ts +18 -0
- package/dist/ui/radial/RadialPill.js +15 -0
- package/dist/ui/radial/index.d.ts +16 -0
- package/dist/ui/radial/index.js +18 -0
- package/dist/ui/radial/radialMenuStore.d.ts +31 -0
- package/dist/ui/radial/radialMenuStore.js +122 -0
- package/dist/ui/radial/radialMenuViewport.d.ts +6 -0
- package/dist/ui/radial/radialMenuViewport.js +59 -0
- package/dist/ui/radial/useRadialMenu.d.ts +35 -0
- package/dist/ui/radial/useRadialMenu.js +107 -0
- package/dist/ui/showcase.d.ts +14 -6
- package/dist/ui/showcase.js +13 -21
- package/dist/ui/tokens.d.ts +5 -19
- package/dist/ui/tokens.js +5 -21
- package/dist/ui.d.ts +14 -0
- package/dist/ui.js +15 -0
- package/package.json +145 -146
package/dist/ui/jimbo.css
CHANGED
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
|
|
173
173
|
|
|
174
174
|
/* ── Button ────────────────────────────────────────────────────────────── */
|
|
175
|
-
/* Chunky 3D press:
|
|
175
|
+
/* Chunky 3D press: black underside via drop shadow,
|
|
176
176
|
press sinks the face +3px and collapses the shadow. */
|
|
177
177
|
|
|
178
178
|
.j-btn {
|
|
@@ -186,7 +186,8 @@
|
|
|
186
186
|
.j-btn::after {
|
|
187
187
|
content: '';
|
|
188
188
|
position: absolute;
|
|
189
|
-
inset:
|
|
189
|
+
inset: 0;
|
|
190
|
+
background: transparent;
|
|
190
191
|
z-index: 10;
|
|
191
192
|
}
|
|
192
193
|
.j-btn--full { width: 100%; }
|
|
@@ -195,42 +196,38 @@
|
|
|
195
196
|
cursor: not-allowed;
|
|
196
197
|
}
|
|
197
198
|
|
|
198
|
-
.j-btn__shadow {
|
|
199
|
-
position: absolute;
|
|
200
|
-
left: 1px;
|
|
201
|
-
top: 3px;
|
|
202
|
-
right: -1px;
|
|
203
|
-
bottom: -3px;
|
|
204
|
-
border-radius: var(--j-radius-md);
|
|
205
|
-
background: var(--j-btn-shadow-color, var(--j-dark-orange));
|
|
206
|
-
transition: opacity var(--j-press-speed) linear;
|
|
207
|
-
}
|
|
208
|
-
.j-btn[data-pressed="true"] .j-btn__shadow { opacity: 0; }
|
|
209
|
-
|
|
210
199
|
.j-btn__face {
|
|
211
200
|
position: relative;
|
|
212
201
|
border-radius: var(--j-radius-md);
|
|
213
202
|
background: var(--j-btn-face-color, var(--j-orange));
|
|
214
203
|
text-align: center;
|
|
215
204
|
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.8);
|
|
205
|
+
box-shadow: 0 var(--j-press-y) 0 0 rgba(0, 0, 0, 0.6);
|
|
216
206
|
transform: translate(0, 0);
|
|
217
|
-
transition: transform var(--j-press-speed) linear;
|
|
207
|
+
transition: transform var(--j-press-speed) linear, box-shadow var(--j-press-speed) linear;
|
|
218
208
|
}
|
|
219
209
|
.j-btn[data-pressed="true"] .j-btn__face {
|
|
220
|
-
transform:
|
|
210
|
+
transform: translateY(var(--j-press-y));
|
|
211
|
+
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.6);
|
|
212
|
+
}
|
|
213
|
+
.j-btn:not(.j-btn--disabled):hover .j-btn__face {
|
|
214
|
+
filter: brightness(1.1);
|
|
221
215
|
}
|
|
222
216
|
|
|
223
217
|
/* Sizes */
|
|
224
|
-
.j-btn--xs .j-btn__face { padding:
|
|
225
|
-
.j-btn--sm .j-btn__face { padding:
|
|
226
|
-
.j-btn--md .j-btn__face { padding:
|
|
227
|
-
.j-btn--lg .j-btn__face { padding:
|
|
218
|
+
.j-btn--xs .j-btn__face { padding: 4px 8px; font-size: 11px; }
|
|
219
|
+
.j-btn--sm .j-btn__face { padding: 6px 12px; font-size: 13px; }
|
|
220
|
+
.j-btn--md .j-btn__face { padding: 10px 18px; font-size: 16px; }
|
|
221
|
+
.j-btn--lg .j-btn__face { padding: 8px 18px; font-size: 20px; }
|
|
228
222
|
|
|
229
223
|
/* Tone colors — set via CSS custom properties */
|
|
230
|
-
.j-btn--orange
|
|
231
|
-
.j-btn--red
|
|
232
|
-
.j-btn--blue
|
|
233
|
-
.j-btn--green
|
|
224
|
+
.j-btn--orange { --j-btn-face-color: var(--j-orange); }
|
|
225
|
+
.j-btn--red { --j-btn-face-color: var(--j-red); }
|
|
226
|
+
.j-btn--blue { --j-btn-face-color: var(--j-blue); }
|
|
227
|
+
.j-btn--green { --j-btn-face-color: var(--j-green); }
|
|
228
|
+
.j-btn--tarot { --j-btn-face-color: var(--j-tarot-btn); }
|
|
229
|
+
.j-btn--planet { --j-btn-face-color: var(--j-planet-btn); }
|
|
230
|
+
.j-btn--spectral { --j-btn-face-color: var(--j-spectral-btn); }
|
|
234
231
|
|
|
235
232
|
|
|
236
233
|
/* ── Badge ─────────────────────────────────────────────────────────────── */
|
|
@@ -249,13 +246,13 @@
|
|
|
249
246
|
.j-badge--sm { padding: 2px 6px; font-size: 10px; }
|
|
250
247
|
.j-badge--md { padding: 4px 8px; font-size: 12px; }
|
|
251
248
|
|
|
252
|
-
/* Badge tones —
|
|
253
|
-
.j-badge--dark { background: var(--j-darkest); color: var(--j-white);
|
|
254
|
-
.j-badge--blue { background: var(--j-blue); color: var(--j-white);
|
|
255
|
-
.j-badge--red { background: var(--j-red); color: var(--j-white);
|
|
256
|
-
.j-badge--green { background: var(--j-green); color: var(--j-white);
|
|
257
|
-
.j-badge--orange { background: var(--j-orange); color: var(--j-white);
|
|
258
|
-
.j-badge--purple { background: var(--j-purple); color: var(--j-white);
|
|
249
|
+
/* Badge tones — flat, no shadow, no edges */
|
|
250
|
+
.j-badge--dark { background: var(--j-darkest); color: var(--j-white); }
|
|
251
|
+
.j-badge--blue { background: var(--j-blue); color: var(--j-white); }
|
|
252
|
+
.j-badge--red { background: var(--j-red); color: var(--j-white); }
|
|
253
|
+
.j-badge--green { background: var(--j-green); color: var(--j-white); }
|
|
254
|
+
.j-badge--orange { background: var(--j-orange); color: var(--j-white); }
|
|
255
|
+
.j-badge--purple { background: var(--j-purple); color: var(--j-white); }
|
|
259
256
|
|
|
260
257
|
|
|
261
258
|
/* ── Tabs ──────────────────────────────────────────────────────────────── */
|
|
@@ -632,6 +629,48 @@
|
|
|
632
629
|
opacity: 0.85;
|
|
633
630
|
}
|
|
634
631
|
|
|
632
|
+
/* ── FlankNav ───────────────────────────────────────────────────────────── */
|
|
633
|
+
|
|
634
|
+
.j-flank {
|
|
635
|
+
display: flex;
|
|
636
|
+
align-items: center;
|
|
637
|
+
justify-content: center;
|
|
638
|
+
gap: var(--j-space-md);
|
|
639
|
+
width: 100%;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
.j-flank__content {
|
|
643
|
+
flex: 1;
|
|
644
|
+
display: flex;
|
|
645
|
+
justify-content: center;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
.j-flank__btn {
|
|
649
|
+
background: var(--j-red);
|
|
650
|
+
color: var(--j-white);
|
|
651
|
+
border: none;
|
|
652
|
+
border-radius: var(--j-radius-sm);
|
|
653
|
+
padding: var(--j-space-sm) var(--j-space-xs);
|
|
654
|
+
cursor: pointer;
|
|
655
|
+
box-shadow: 0 var(--j-press-y) 0 var(--j-dark-grey);
|
|
656
|
+
transition: transform 0.05s ease, box-shadow 0.05s ease, opacity 0.2s ease;
|
|
657
|
+
display: flex;
|
|
658
|
+
align-items: center;
|
|
659
|
+
justify-content: center;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
.j-flank__btn[data-pressed="true"] {
|
|
663
|
+
transform: translateY(var(--j-press-y));
|
|
664
|
+
box-shadow: 0 0 0 var(--j-dark-grey);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
.j-flank__btn:disabled {
|
|
668
|
+
opacity: 0.5;
|
|
669
|
+
cursor: not-allowed;
|
|
670
|
+
transform: none;
|
|
671
|
+
box-shadow: 0 var(--j-press-y) 0 var(--j-dark-grey);
|
|
672
|
+
}
|
|
673
|
+
|
|
635
674
|
|
|
636
675
|
/* ── Modal ────────────────────────────────────────────────────────────── */
|
|
637
676
|
|
|
@@ -743,6 +782,272 @@
|
|
|
743
782
|
.j-overflow-auto { overflow: auto; }
|
|
744
783
|
.j-relative { position: relative; }
|
|
745
784
|
|
|
785
|
+
/* Tone border utilities */
|
|
786
|
+
.j-border--red { border-color: var(--j-red); }
|
|
787
|
+
.j-border--blue { border-color: var(--j-blue); }
|
|
788
|
+
.j-border--green { border-color: var(--j-green); }
|
|
789
|
+
.j-border--gold { border-color: var(--j-gold); }
|
|
790
|
+
.j-border--orange { border-color: var(--j-orange); }
|
|
791
|
+
.j-border--purple { border-color: var(--j-purple); }
|
|
792
|
+
|
|
793
|
+
/* Tone background utilities */
|
|
794
|
+
.j-bg--red { background-color: var(--j-red); }
|
|
795
|
+
.j-bg--blue { background-color: var(--j-blue); }
|
|
796
|
+
.j-bg--green { background-color: var(--j-green); }
|
|
797
|
+
.j-bg--gold { background-color: var(--j-gold); }
|
|
798
|
+
.j-bg--orange { background-color: var(--j-orange); }
|
|
799
|
+
.j-bg--purple { background-color: var(--j-purple); }
|
|
800
|
+
.j-bg--dark-grey { background-color: var(--j-dark-grey); }
|
|
801
|
+
.j-bg--darkest { background-color: var(--j-darkest); }
|
|
802
|
+
|
|
803
|
+
/* ── App Shell ────────────────────────────────────────────────────────── */
|
|
804
|
+
/* Mobile-first 375px layout container for ALL Jimbo UI screens.
|
|
805
|
+
* Supports container queries for responsive breakpoints:
|
|
806
|
+
* compact ≤400px — iPhone SE, fixed 667px height, NO scroll
|
|
807
|
+
* cozy 401-750px — MCP inline / wider phones, flexible height, scroll OK
|
|
808
|
+
* wide 751px+ — tablet/desktop, two-column layouts (future)
|
|
809
|
+
*
|
|
810
|
+
* Default = compact (hard lock). Add .j-app--fluid to unlock for MCP/desktop.
|
|
811
|
+
*/
|
|
812
|
+
|
|
813
|
+
.j-app {
|
|
814
|
+
container-type: inline-size;
|
|
815
|
+
container-name: jimbo;
|
|
816
|
+
width: 375px;
|
|
817
|
+
max-width: 375px;
|
|
818
|
+
height: 667px;
|
|
819
|
+
max-height: 667px;
|
|
820
|
+
margin: 0 auto;
|
|
821
|
+
display: flex;
|
|
822
|
+
flex-direction: column;
|
|
823
|
+
background: var(--j-darkest);
|
|
824
|
+
font-family: var(--j-font);
|
|
825
|
+
color: var(--j-white);
|
|
826
|
+
overflow: hidden;
|
|
827
|
+
position: relative;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/* Fluid modifier — unlocks the container for MCP / desktop contexts. */
|
|
831
|
+
.j-app--fluid {
|
|
832
|
+
width: 100%;
|
|
833
|
+
max-width: 750px;
|
|
834
|
+
height: auto;
|
|
835
|
+
max-height: none;
|
|
836
|
+
min-height: 400px;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
.j-app__content {
|
|
840
|
+
flex: 1;
|
|
841
|
+
min-height: 0;
|
|
842
|
+
overflow: hidden;
|
|
843
|
+
padding: var(--j-space-lg) var(--j-space-lg) var(--j-space-md);
|
|
844
|
+
display: flex;
|
|
845
|
+
flex-direction: column;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
.j-app__scroll {
|
|
849
|
+
flex: 1;
|
|
850
|
+
min-height: 0;
|
|
851
|
+
overflow-y: auto;
|
|
852
|
+
overflow-x: hidden;
|
|
853
|
+
padding: var(--j-space-lg) var(--j-space-lg) var(--j-space-md);
|
|
854
|
+
scrollbar-width: none;
|
|
855
|
+
-ms-overflow-style: none;
|
|
856
|
+
}
|
|
857
|
+
.j-app__scroll::-webkit-scrollbar { display: none; }
|
|
858
|
+
|
|
859
|
+
.j-app__footer {
|
|
860
|
+
flex-shrink: 0;
|
|
861
|
+
padding: var(--j-space-md) var(--j-space-lg) var(--j-space-md);
|
|
862
|
+
border-top: 2px solid var(--j-black);
|
|
863
|
+
background: var(--j-dark-grey);
|
|
864
|
+
display: flex;
|
|
865
|
+
flex-direction: column;
|
|
866
|
+
gap: var(--j-space-sm);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/* ── Cozy Breakpoint (401px+) ──────────────────────────────────────── */
|
|
870
|
+
/* Only activates when j-app--fluid is used AND container is wide enough. */
|
|
871
|
+
|
|
872
|
+
@container jimbo (min-width: 401px) {
|
|
873
|
+
.j-app__content {
|
|
874
|
+
padding: var(--j-space-xl) var(--j-space-xl) var(--j-space-lg);
|
|
875
|
+
}
|
|
876
|
+
.j-app__scroll {
|
|
877
|
+
padding: var(--j-space-xl) var(--j-space-xl) var(--j-space-lg);
|
|
878
|
+
}
|
|
879
|
+
.j-app__footer {
|
|
880
|
+
padding: var(--j-space-md) var(--j-space-xl) var(--j-space-lg);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
@container jimbo (min-width: 401px) {
|
|
885
|
+
.j-stat-grid__value {
|
|
886
|
+
font-size: 20px;
|
|
887
|
+
}
|
|
888
|
+
.j-info-card {
|
|
889
|
+
padding: var(--j-space-md) var(--j-space-lg);
|
|
890
|
+
}
|
|
891
|
+
.j-info-card__title {
|
|
892
|
+
font-size: 14px;
|
|
893
|
+
}
|
|
894
|
+
.j-section-header__tag {
|
|
895
|
+
font-size: 12px;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
/* ── Section Header ──────────────────────────────────────────────────── */
|
|
901
|
+
/* Colored tag + horizontal rule — reusable section divider. */
|
|
902
|
+
|
|
903
|
+
.j-section-header {
|
|
904
|
+
display: flex;
|
|
905
|
+
align-items: center;
|
|
906
|
+
gap: var(--j-space-md);
|
|
907
|
+
margin-bottom: var(--j-space-md);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.j-section-header__tag {
|
|
911
|
+
font-family: var(--j-font);
|
|
912
|
+
font-size: 11px;
|
|
913
|
+
letter-spacing: 2px;
|
|
914
|
+
padding: 2px 8px;
|
|
915
|
+
color: var(--j-white);
|
|
916
|
+
border-radius: 3px;
|
|
917
|
+
text-shadow: var(--j-text-shadow);
|
|
918
|
+
flex-shrink: 0;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
.j-section-header__rule {
|
|
922
|
+
flex: 1;
|
|
923
|
+
height: 2px;
|
|
924
|
+
border-radius: 1px;
|
|
925
|
+
opacity: 0.33;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
/* ── Stat Grid ───────────────────────────────────────────────────────── */
|
|
930
|
+
/* 3-column stat bar — reusable primitive. */
|
|
931
|
+
|
|
932
|
+
.j-stat-grid {
|
|
933
|
+
background: var(--j-dark-grey);
|
|
934
|
+
border-radius: var(--j-radius-md);
|
|
935
|
+
padding: var(--j-space-md);
|
|
936
|
+
border: 2px solid var(--j-panel-edge);
|
|
937
|
+
box-shadow: 0 2px 0 var(--j-black);
|
|
938
|
+
display: grid;
|
|
939
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
940
|
+
gap: var(--j-space-md);
|
|
941
|
+
text-align: center;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
.j-stat-grid__value {
|
|
945
|
+
font-family: var(--j-font);
|
|
946
|
+
font-size: 16px;
|
|
947
|
+
color: var(--j-gold-text);
|
|
948
|
+
text-shadow: var(--j-text-shadow);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
.j-stat-grid__label {
|
|
952
|
+
font-family: var(--j-font);
|
|
953
|
+
font-size: 9px;
|
|
954
|
+
color: var(--j-grey);
|
|
955
|
+
letter-spacing: 2px;
|
|
956
|
+
margin-top: 2px;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
|
|
960
|
+
/* ── Info Card ───────────────────────────────────────────────────────── */
|
|
961
|
+
/* Generic clickable row card — used for filter lists, seed lists, etc. */
|
|
962
|
+
|
|
963
|
+
.j-info-card {
|
|
964
|
+
background: var(--j-dark-grey);
|
|
965
|
+
border-radius: var(--j-radius-md);
|
|
966
|
+
padding: var(--j-space-md);
|
|
967
|
+
box-shadow: 0 2px 0 var(--j-black);
|
|
968
|
+
display: flex;
|
|
969
|
+
align-items: center;
|
|
970
|
+
gap: var(--j-space-md);
|
|
971
|
+
cursor: pointer;
|
|
972
|
+
border: 2px solid transparent;
|
|
973
|
+
}
|
|
974
|
+
.j-info-card:hover {
|
|
975
|
+
filter: brightness(1.08);
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
.j-info-card__body {
|
|
979
|
+
flex: 1;
|
|
980
|
+
min-width: 0;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
.j-info-card__title {
|
|
984
|
+
font-family: var(--j-font);
|
|
985
|
+
font-size: 13px;
|
|
986
|
+
color: var(--j-white);
|
|
987
|
+
letter-spacing: 1px;
|
|
988
|
+
text-shadow: var(--j-text-shadow);
|
|
989
|
+
overflow: hidden;
|
|
990
|
+
text-overflow: ellipsis;
|
|
991
|
+
white-space: nowrap;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
.j-info-card__sub {
|
|
995
|
+
font-family: var(--j-font);
|
|
996
|
+
font-size: 9px;
|
|
997
|
+
color: var(--j-gold-text);
|
|
998
|
+
letter-spacing: 1px;
|
|
999
|
+
margin-top: 2px;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
.j-info-card__aside {
|
|
1003
|
+
text-align: right;
|
|
1004
|
+
flex-shrink: 0;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
/* ── Inset Box ───────────────────────────────────────────────────────── */
|
|
1009
|
+
/* Dark recessed content area — for log output, recent finds, etc. */
|
|
1010
|
+
|
|
1011
|
+
.j-inset {
|
|
1012
|
+
background: var(--j-dark-grey);
|
|
1013
|
+
border-radius: var(--j-radius-md);
|
|
1014
|
+
padding: var(--j-space-md) var(--j-space-md);
|
|
1015
|
+
border: 2px solid var(--j-panel-edge);
|
|
1016
|
+
box-shadow: 0 2px 0 var(--j-black);
|
|
1017
|
+
font-family: var(--j-font);
|
|
1018
|
+
font-size: 11px;
|
|
1019
|
+
color: var(--j-grey);
|
|
1020
|
+
letter-spacing: 1px;
|
|
1021
|
+
line-height: 1.7;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
/* ── Wordmark ────────────────────────────────────────────────────────── */
|
|
1026
|
+
/* Title + subtitle hero block. */
|
|
1027
|
+
|
|
1028
|
+
.j-wordmark {
|
|
1029
|
+
text-align: center;
|
|
1030
|
+
margin-bottom: var(--j-space-xl);
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
.j-wordmark__title {
|
|
1034
|
+
font-family: var(--j-font);
|
|
1035
|
+
font-size: 32px;
|
|
1036
|
+
letter-spacing: 3px;
|
|
1037
|
+
line-height: 1;
|
|
1038
|
+
color: var(--j-gold-text);
|
|
1039
|
+
text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.8);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
.j-wordmark__sub {
|
|
1043
|
+
font-family: var(--j-font);
|
|
1044
|
+
font-size: 14px;
|
|
1045
|
+
letter-spacing: 4px;
|
|
1046
|
+
color: var(--j-grey);
|
|
1047
|
+
margin-top: 4px;
|
|
1048
|
+
text-shadow: var(--j-text-shadow);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
746
1051
|
|
|
747
1052
|
/* ── Seed Input ───────────────────────────────────────────────────────── */
|
|
748
1053
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface JimboAppProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
/** Unlock width/height for MCP inline or desktop use. Default: false (375×667 locked). */
|
|
5
|
+
fluid?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** Standard mobile-first app shell. 375px locked, or fluid for MCP/desktop. */
|
|
8
|
+
export declare function JimboApp({ children, fluid, className, ...props }: JimboAppProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
/** Scrollable content area inside JimboApp. Hidden scrollbar, snap-friendly. */
|
|
10
|
+
export declare function JimboAppScroll({ children, className, ...props }: Omit<JimboAppProps, 'fluid'>): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
/** Sticky bottom action area inside JimboApp. Thumb zone. */
|
|
12
|
+
export declare function JimboAppFooter({ children, className, ...props }: Omit<JimboAppProps, 'fluid'>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/** Standard mobile-first app shell. 375px locked, or fluid for MCP/desktop. */
|
|
4
|
+
export function JimboApp({ children, fluid, className = '', ...props }) {
|
|
5
|
+
const classes = `j-app${fluid ? ' j-app--fluid' : ''} ${className}`.trim();
|
|
6
|
+
return (_jsx("div", { className: classes, ...props, children: children }));
|
|
7
|
+
}
|
|
8
|
+
/** Scrollable content area inside JimboApp. Hidden scrollbar, snap-friendly. */
|
|
9
|
+
export function JimboAppScroll({ children, className = '', ...props }) {
|
|
10
|
+
return (_jsx("div", { className: `j-app__scroll ${className}`, ...props, children: children }));
|
|
11
|
+
}
|
|
12
|
+
/** Sticky bottom action area inside JimboApp. Thumb zone. */
|
|
13
|
+
export function JimboAppFooter({ children, className = '', ...props }) {
|
|
14
|
+
return (_jsx("div", { className: `j-app__footer ${className}`, ...props, children: children }));
|
|
15
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type JimboInfoCardTone = 'red' | 'blue' | 'green' | 'gold' | 'orange' | 'purple';
|
|
3
|
+
export interface JimboInfoCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
tone?: JimboInfoCardTone;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Generic clickable row card — used for filter lists, seed lists, etc.
|
|
9
|
+
* Border color set via tone. All styling via jimbo.css `.j-info-card`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function JimboInfoCard({ tone, children, className, ...props }: JimboInfoCardProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
/** Main body area inside an InfoCard (flex: 1, overflow-safe). */
|
|
13
|
+
export declare function JimboInfoCardBody({ children, className }: {
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
/** Title line inside an InfoCard body. */
|
|
18
|
+
export declare function JimboInfoCardTitle({ children, className }: {
|
|
19
|
+
children: React.ReactNode;
|
|
20
|
+
className?: string;
|
|
21
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
/** Subtitle line inside an InfoCard body. */
|
|
23
|
+
export declare function JimboInfoCardSub({ children, className }: {
|
|
24
|
+
children: React.ReactNode;
|
|
25
|
+
className?: string;
|
|
26
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
/** Right-side aside area inside an InfoCard. */
|
|
28
|
+
export declare function JimboInfoCardAside({ children, className }: {
|
|
29
|
+
children: React.ReactNode;
|
|
30
|
+
className?: string;
|
|
31
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Generic clickable row card — used for filter lists, seed lists, etc.
|
|
5
|
+
* Border color set via tone. All styling via jimbo.css `.j-info-card`.
|
|
6
|
+
*/
|
|
7
|
+
export function JimboInfoCard({ tone, children, className = '', ...props }) {
|
|
8
|
+
const borderClass = tone ? `j-border--${tone}` : '';
|
|
9
|
+
return (_jsx("div", { className: `j-info-card ${borderClass} ${className}`, style: tone ? { borderColor: undefined } : undefined, ...props, children: children }));
|
|
10
|
+
}
|
|
11
|
+
/** Main body area inside an InfoCard (flex: 1, overflow-safe). */
|
|
12
|
+
export function JimboInfoCardBody({ children, className = '' }) {
|
|
13
|
+
return _jsx("div", { className: `j-info-card__body ${className}`, children: children });
|
|
14
|
+
}
|
|
15
|
+
/** Title line inside an InfoCard body. */
|
|
16
|
+
export function JimboInfoCardTitle({ children, className = '' }) {
|
|
17
|
+
return _jsx("div", { className: `j-info-card__title ${className}`, children: children });
|
|
18
|
+
}
|
|
19
|
+
/** Subtitle line inside an InfoCard body. */
|
|
20
|
+
export function JimboInfoCardSub({ children, className = '' }) {
|
|
21
|
+
return _jsx("div", { className: `j-info-card__sub ${className}`, children: children });
|
|
22
|
+
}
|
|
23
|
+
/** Right-side aside area inside an InfoCard. */
|
|
24
|
+
export function JimboInfoCardAside({ children, className = '' }) {
|
|
25
|
+
return _jsx("div", { className: `j-info-card__aside ${className}`, children: children });
|
|
26
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface JimboInsetProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Dark recessed content area — for log output, recent finds, etc.
|
|
7
|
+
* All styling via jimbo.css `.j-inset` class.
|
|
8
|
+
*/
|
|
9
|
+
export declare function JimboInset({ children, className, ...props }: JimboInsetProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Dark recessed content area — for log output, recent finds, etc.
|
|
5
|
+
* All styling via jimbo.css `.j-inset` class.
|
|
6
|
+
*/
|
|
7
|
+
export function JimboInset({ children, className = '', ...props }) {
|
|
8
|
+
return (_jsx("div", { className: `j-inset ${className}`, ...props, children: children }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type JimboSectionTone = 'red' | 'blue' | 'green' | 'gold' | 'orange' | 'purple';
|
|
2
|
+
export interface JimboSectionHeaderProps {
|
|
3
|
+
label: string;
|
|
4
|
+
tone?: JimboSectionTone;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Colored tag + horizontal rule — reusable section divider.
|
|
9
|
+
* All styling via jimbo.css `.j-section-header` classes + tone utilities.
|
|
10
|
+
*/
|
|
11
|
+
export declare function JimboSectionHeader({ label, tone, className }: JimboSectionHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Colored tag + horizontal rule — reusable section divider.
|
|
5
|
+
* All styling via jimbo.css `.j-section-header` classes + tone utilities.
|
|
6
|
+
*/
|
|
7
|
+
export function JimboSectionHeader({ label, tone = 'blue', className = '' }) {
|
|
8
|
+
return (_jsxs("div", { className: `j-section-header ${className}`, children: [_jsx("div", { className: `j-section-header__tag j-bg--${tone}`, children: label }), _jsx("div", { className: `j-section-header__rule j-bg--${tone}` })] }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface JimboStatItem {
|
|
3
|
+
value: string | number;
|
|
4
|
+
label: string;
|
|
5
|
+
}
|
|
6
|
+
export interface JimboStatGridProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
7
|
+
items: JimboStatItem[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 3-column stat bar — value on top, label below.
|
|
11
|
+
* All styling via jimbo.css `.j-stat-grid` classes.
|
|
12
|
+
*/
|
|
13
|
+
export declare function JimboStatGrid({ items, className, ...props }: JimboStatGridProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* 3-column stat bar — value on top, label below.
|
|
5
|
+
* All styling via jimbo.css `.j-stat-grid` classes.
|
|
6
|
+
*/
|
|
7
|
+
export function JimboStatGrid({ items, className = '', ...props }) {
|
|
8
|
+
return (_jsx("div", { className: `j-stat-grid ${className}`, ...props, children: items.map((item) => (_jsxs("div", { children: [_jsx("div", { className: "j-stat-grid__value", children: item.value }), _jsx("div", { className: "j-stat-grid__label", children: item.label })] }, item.label))) }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface JimboWordmarkProps {
|
|
2
|
+
title: string;
|
|
3
|
+
subtitle?: string;
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Title + subtitle hero block. Gold title, grey subtitle.
|
|
8
|
+
* All styling via jimbo.css `.j-wordmark` classes.
|
|
9
|
+
*/
|
|
10
|
+
export declare function JimboWordmark({ title, subtitle, className }: JimboWordmarkProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Title + subtitle hero block. Gold title, grey subtitle.
|
|
5
|
+
* All styling via jimbo.css `.j-wordmark` classes.
|
|
6
|
+
*/
|
|
7
|
+
export function JimboWordmark({ title, subtitle, className = '' }) {
|
|
8
|
+
return (_jsxs("div", { className: `j-wordmark ${className}`, children: [_jsx("div", { className: "j-wordmark__title", children: title }), subtitle && _jsx("div", { className: "j-wordmark__sub", children: subtitle })] }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function JammySpeechBox({ text, highlightPos, activeSentenceRange, className, }: {
|
|
2
|
+
text: string | null;
|
|
3
|
+
highlightPos?: number | null;
|
|
4
|
+
activeSentenceRange?: {
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
} | null;
|
|
8
|
+
className?: string;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { splitTtsDisplay } from '../../lib/tts/splitTtsDisplay';
|
|
4
|
+
/** Fixed chrome so the home announcement always occupies one predictable size (ai-elements, same family as chat). */
|
|
5
|
+
const speechBoxFrame = 'w-[20.5rem] max-w-[calc(100vw-2.25rem)] min-h-[7.25rem] h-[7.25rem] rounded-xl border border-white/15 bg-black/72 px-4 py-3 text-center shadow-lg backdrop-blur-md';
|
|
6
|
+
const speechText = 'whitespace-pre-wrap break-words text-sm font-normal leading-relaxed tracking-normal text-[#f6f0d5] antialiased';
|
|
7
|
+
// Simple utility to concatenate classes instead of importing tailwind-merge (for agnostic component)
|
|
8
|
+
function cn(...classes) {
|
|
9
|
+
return classes.filter(Boolean).join(' ');
|
|
10
|
+
}
|
|
11
|
+
export function JammySpeechBox({ text, highlightPos, activeSentenceRange, className, }) {
|
|
12
|
+
const raw = (text ?? '').trim();
|
|
13
|
+
if (!raw)
|
|
14
|
+
return null;
|
|
15
|
+
const split = splitTtsDisplay(raw, highlightPos, activeSentenceRange, { stripMarkdown: true });
|
|
16
|
+
const ttsOff = highlightPos == null;
|
|
17
|
+
const displaySource = split
|
|
18
|
+
? `${split.prefix}${split.spoken}${split.pending}${split.suffix}`
|
|
19
|
+
: raw.replace(/```[\s\S]*?```/g, '').replace(/\*\*/g, '').trim();
|
|
20
|
+
if (!displaySource)
|
|
21
|
+
return null;
|
|
22
|
+
const prefix = ttsOff || !split ? '' : split.prefix;
|
|
23
|
+
const spoken = !split || ttsOff ? displaySource : split.spoken;
|
|
24
|
+
const pending = !split || ttsOff ? '' : split.pending;
|
|
25
|
+
const suffix = !split || ttsOff ? '' : split.suffix;
|
|
26
|
+
return (_jsx("div", { "data-testid": "jammy-announcement", className: cn(
|
|
27
|
+
// Anchor to the scene center so Jammy stays centered inside the orbital menu,
|
|
28
|
+
// with the announcement floating just above the mascot's head.
|
|
29
|
+
'pointer-events-none absolute top-1/2 left-1/2 z-20 flex w-full max-w-[calc(100vw-2.25rem)] -translate-x-1/2 -translate-y-[calc(100%+5.75rem)] justify-center sm:-translate-y-[calc(100%+6.25rem)]', className), children: _jsx("div", { className: "max-w-none", children: _jsx("div", { className: cn(speechBoxFrame, 'flex flex-col items-center justify-center overflow-hidden text-[#f6f0d5]!'), children: _jsxs("p", { className: cn(speechText, 'm-0 w-full max-w-full'), children: [_jsx("span", { className: "text-[#f6f0d5]", children: prefix }), _jsx("span", { className: "text-[#f6f0d5]", children: spoken }), _jsx("span", { className: "text-[#f6f0d5]/35", children: pending }), _jsx("span", { className: "text-[#f6f0d5]/35", children: suffix })] }) }) }) }));
|
|
30
|
+
}
|