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.
Files changed (119) hide show
  1. package/DESIGN.md +36 -6
  2. package/dist/components/JamlAnalyzerFullscreen.d.ts +1 -1
  3. package/dist/components/JamlAnalyzerFullscreen.js +5 -81
  4. package/dist/components/JamlCurator.js +1 -1
  5. package/dist/components/JamlSpeedometer.d.ts +7 -2
  6. package/dist/components/JamlSpeedometer.js +8 -15
  7. package/dist/components/jamlMap/JamlMapEditor.js +42 -38
  8. package/dist/components/jamlMap/JokerPicker.js +2 -2
  9. package/dist/components/jamlMap/MysterySlot.js +4 -4
  10. package/dist/hooks/useSearch.d.ts +2 -1
  11. package/dist/hooks/useSearch.js +111 -8
  12. package/dist/lib/SpriteMapper.d.ts +10 -0
  13. package/dist/lib/SpriteMapper.js +48 -0
  14. package/dist/lib/cardParser.d.ts +8 -0
  15. package/dist/lib/cardParser.js +65 -0
  16. package/dist/lib/classes/BuyMetaData.d.ts +11 -0
  17. package/dist/lib/classes/BuyMetaData.js +1 -0
  18. package/dist/lib/config.d.ts +13 -0
  19. package/dist/lib/config.js +15 -0
  20. package/dist/lib/const.d.ts +61 -0
  21. package/dist/lib/const.js +521 -0
  22. package/dist/lib/data/constants.d.ts +11 -0
  23. package/dist/lib/data/constants.js +17 -0
  24. package/dist/lib/hooks/useDragScroll.d.ts +4 -0
  25. package/dist/lib/hooks/useDragScroll.js +48 -0
  26. package/dist/lib/hooks/useJamlFilter.d.ts +48 -0
  27. package/dist/lib/hooks/useJamlFilter.js +219 -0
  28. package/dist/lib/hooks/useSeedAnalyzer.d.ts +6 -0
  29. package/dist/lib/hooks/useSeedAnalyzer.js +48 -0
  30. package/dist/lib/jaml/jamlCompletion.d.ts +12 -0
  31. package/dist/lib/jaml/jamlCompletion.js +13 -0
  32. package/dist/lib/jaml/jamlData.d.ts +3 -0
  33. package/dist/lib/jaml/jamlData.js +8 -0
  34. package/dist/lib/jaml/jamlObjectives.d.ts +13 -0
  35. package/dist/lib/jaml/jamlObjectives.js +97 -0
  36. package/dist/lib/jaml/jamlParser.d.ts +14 -0
  37. package/dist/lib/jaml/jamlParser.js +47 -0
  38. package/dist/lib/jaml/jamlPresets.d.ts +8 -0
  39. package/dist/lib/jaml/jamlPresets.js +61 -0
  40. package/dist/lib/jaml/jamlSchema.d.ts +54 -0
  41. package/dist/lib/jaml/jamlSchema.js +91 -0
  42. package/dist/lib/parseDailyRitual.d.ts +45 -0
  43. package/dist/lib/parseDailyRitual.js +69 -0
  44. package/dist/lib/tts/getRevealPos.d.ts +5 -0
  45. package/dist/lib/tts/getRevealPos.js +16 -0
  46. package/dist/lib/tts/splitTtsDisplay.d.ts +19 -0
  47. package/dist/lib/tts/splitTtsDisplay.js +35 -0
  48. package/dist/lib/types.d.ts +121 -0
  49. package/dist/lib/types.js +1 -0
  50. package/dist/lib/utils.d.ts +2 -0
  51. package/dist/lib/utils.js +5 -0
  52. package/dist/ui/JimboIconButton.d.ts +10 -0
  53. package/dist/ui/JimboIconButton.js +28 -0
  54. package/dist/ui/JimboInputModal.d.ts +13 -0
  55. package/dist/ui/JimboInputModal.js +60 -0
  56. package/dist/ui/JimboSelect.d.ts +18 -0
  57. package/dist/ui/JimboSelect.js +43 -0
  58. package/dist/ui/PanelSplitter.d.ts +7 -0
  59. package/dist/ui/PanelSplitter.js +76 -0
  60. package/dist/ui/ide/AgnosticSeedCard.d.ts +19 -0
  61. package/dist/ui/ide/AgnosticSeedCard.js +48 -0
  62. package/dist/ui/ide/DeckSprite.d.ts +1 -0
  63. package/dist/ui/ide/DeckSprite.js +2 -0
  64. package/dist/ui/ide/JamlBuilder.d.ts +1 -0
  65. package/dist/ui/ide/JamlBuilder.js +112 -0
  66. package/dist/ui/ide/JamlEditor.d.ts +7 -0
  67. package/dist/ui/ide/JamlEditor.js +496 -0
  68. package/dist/ui/ide/JamlEditorMonaco.d.ts +8 -0
  69. package/dist/ui/ide/JamlEditorMonaco.js +78 -0
  70. package/dist/ui/ide/WasmStatus.d.ts +1 -0
  71. package/dist/ui/ide/WasmStatus.js +42 -0
  72. package/dist/ui/jimbo.css +336 -31
  73. package/dist/ui/jimboApp.d.ts +12 -0
  74. package/dist/ui/jimboApp.js +15 -0
  75. package/dist/ui/jimboInfoCard.d.ts +31 -0
  76. package/dist/ui/jimboInfoCard.js +26 -0
  77. package/dist/ui/jimboInset.d.ts +9 -0
  78. package/dist/ui/jimboInset.js +9 -0
  79. package/dist/ui/jimboSectionHeader.d.ts +11 -0
  80. package/dist/ui/jimboSectionHeader.js +9 -0
  81. package/dist/ui/jimboStatGrid.d.ts +13 -0
  82. package/dist/ui/jimboStatGrid.js +9 -0
  83. package/dist/ui/jimboWordmark.d.ts +10 -0
  84. package/dist/ui/jimboWordmark.js +9 -0
  85. package/dist/ui/mascot/JammySpeechBox.d.ts +9 -0
  86. package/dist/ui/mascot/JammySpeechBox.js +30 -0
  87. package/dist/ui/mascot/SeedMascot.d.ts +37 -0
  88. package/dist/ui/mascot/SeedMascot.js +17 -0
  89. package/dist/ui/mascot/index.d.ts +3 -0
  90. package/dist/ui/mascot/index.js +3 -0
  91. package/dist/ui/mascot/menuConfig.d.ts +102 -0
  92. package/dist/ui/mascot/menuConfig.js +12 -0
  93. package/dist/ui/panel.d.ts +1 -1
  94. package/dist/ui/panel.js +3 -21
  95. package/dist/ui/radial/RadialBadge.d.ts +17 -0
  96. package/dist/ui/radial/RadialBadge.js +43 -0
  97. package/dist/ui/radial/RadialBreadcrumb.d.ts +12 -0
  98. package/dist/ui/radial/RadialBreadcrumb.js +18 -0
  99. package/dist/ui/radial/RadialButton.d.ts +61 -0
  100. package/dist/ui/radial/RadialButton.js +102 -0
  101. package/dist/ui/radial/RadialMenu.d.ts +38 -0
  102. package/dist/ui/radial/RadialMenu.js +168 -0
  103. package/dist/ui/radial/RadialPill.d.ts +18 -0
  104. package/dist/ui/radial/RadialPill.js +15 -0
  105. package/dist/ui/radial/index.d.ts +16 -0
  106. package/dist/ui/radial/index.js +18 -0
  107. package/dist/ui/radial/radialMenuStore.d.ts +31 -0
  108. package/dist/ui/radial/radialMenuStore.js +122 -0
  109. package/dist/ui/radial/radialMenuViewport.d.ts +6 -0
  110. package/dist/ui/radial/radialMenuViewport.js +59 -0
  111. package/dist/ui/radial/useRadialMenu.d.ts +35 -0
  112. package/dist/ui/radial/useRadialMenu.js +107 -0
  113. package/dist/ui/showcase.d.ts +14 -6
  114. package/dist/ui/showcase.js +13 -21
  115. package/dist/ui/tokens.d.ts +5 -19
  116. package/dist/ui/tokens.js +5 -21
  117. package/dist/ui.d.ts +14 -0
  118. package/dist/ui.js +15 -0
  119. 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: colored underside via offset shadow div,
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: -4px;
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: translate(1px, 3px);
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: 2px 8px; }
225
- .j-btn--sm .j-btn__face { padding: 4px 10px; }
226
- .j-btn--md .j-btn__face { padding: 6px 14px; }
227
- .j-btn--lg .j-btn__face { padding: 10px 18px; }
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 { --j-btn-face-color: var(--j-orange); --j-btn-shadow-color: var(--j-dark-orange); }
231
- .j-btn--red { --j-btn-face-color: var(--j-red); --j-btn-shadow-color: var(--j-dark-red); }
232
- .j-btn--blue { --j-btn-face-color: var(--j-blue); --j-btn-shadow-color: var(--j-dark-blue); }
233
- .j-btn--green { --j-btn-face-color: var(--j-green); --j-btn-shadow-color: var(--j-dark-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 — dark-colored bottom edge, no thin pixel borders */
253
- .j-badge--dark { background: var(--j-darkest); color: var(--j-white); box-shadow: 0 2px 0 0 var(--j-panel-edge); }
254
- .j-badge--blue { background: var(--j-blue); color: var(--j-white); box-shadow: 0 2px 0 0 var(--j-dark-blue); }
255
- .j-badge--red { background: var(--j-red); color: var(--j-white); box-shadow: 0 2px 0 0 var(--j-dark-red); }
256
- .j-badge--green { background: var(--j-green); color: var(--j-white); box-shadow: 0 2px 0 0 var(--j-dark-green); }
257
- .j-badge--orange { background: var(--j-orange); color: var(--j-white); box-shadow: 0 2px 0 0 var(--j-dark-orange); }
258
- .j-badge--purple { background: var(--j-purple); color: var(--j-white); box-shadow: 0 2px 0 0 var(--j-dark-purple); }
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
+ }