@floegence/floe-webapp-core 0.86.58 → 0.86.62

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 (103) hide show
  1. package/dist/components/chat/blocks/BlockRenderer.js +1 -1
  2. package/dist/components/chat/blocks/CodeDiffBlock.js +56 -56
  3. package/dist/components/chat/blocks/ImageBlock.js +1 -1
  4. package/dist/components/chat/blocks/ToolCallBlock.js +57 -57
  5. package/dist/components/chat/status/ConnectionStatus.js +10 -10
  6. package/dist/components/deck/DeckCell.js +25 -25
  7. package/dist/components/deck/DeckContextMenu.js +20 -20
  8. package/dist/components/deck/DeckGrid.js +1 -1
  9. package/dist/components/deck/DeckTopBar.js +42 -42
  10. package/dist/components/deck/DropZonePreview.js +6 -6
  11. package/dist/components/deck/LayoutSelector.js +53 -53
  12. package/dist/components/deck/WidgetFrame.js +28 -28
  13. package/dist/components/deck/WidgetPalette.js +31 -31
  14. package/dist/components/deck/WidgetTypeSwitcher.js +31 -31
  15. package/dist/components/file-browser/Breadcrumb.js +27 -27
  16. package/dist/components/file-browser/DirectoryTree.js +15 -15
  17. package/dist/components/file-browser/DragPreview.js +58 -58
  18. package/dist/components/file-browser/FileBrowser.js +17 -17
  19. package/dist/components/file-browser/FileBrowserStatusBar.js +18 -18
  20. package/dist/components/file-browser/FileBrowserToolbar.js +27 -27
  21. package/dist/components/file-browser/FileContextMenu.js +47 -47
  22. package/dist/components/file-browser/FileGridView.js +53 -51
  23. package/dist/components/file-browser/FileItemDecorations.js +30 -27
  24. package/dist/components/file-browser/FileListView.js +114 -114
  25. package/dist/components/icons/index.js +1357 -1357
  26. package/dist/components/launchpad/Launchpad.js +14 -14
  27. package/dist/components/launchpad/LaunchpadGrid.js +7 -7
  28. package/dist/components/launchpad/LaunchpadItem.js +11 -11
  29. package/dist/components/launchpad/LaunchpadPagination.js +16 -16
  30. package/dist/components/launchpad/LaunchpadSearch.js +9 -9
  31. package/dist/components/layout/ActivityBar.js +52 -55
  32. package/dist/components/layout/BottomBar.js +17 -17
  33. package/dist/components/layout/MobileNavigationPanel.js +36 -36
  34. package/dist/components/layout/MobileTabBar.js +39 -39
  35. package/dist/components/layout/Panel.js +16 -16
  36. package/dist/components/layout/ResizeHandle.js +19 -19
  37. package/dist/components/layout/Shell.js +50 -50
  38. package/dist/components/layout/Sidebar.js +37 -36
  39. package/dist/components/layout/SidebarPane.js +19 -19
  40. package/dist/components/layout/TopBar.js +16 -16
  41. package/dist/components/layout/TopBarIconButton.js +15 -15
  42. package/dist/components/loading/LoadingOverlay.js +9 -9
  43. package/dist/components/loading/Skeleton.js +11 -11
  44. package/dist/components/ui/Button.js +36 -36
  45. package/dist/components/ui/Card.d.ts +11 -62
  46. package/dist/components/ui/Card.js +64 -237
  47. package/dist/components/ui/Checkbox.js +79 -79
  48. package/dist/components/ui/CommandPalette.js +56 -55
  49. package/dist/components/ui/Dialog.js +91 -93
  50. package/dist/components/ui/DirectoryInput.js +22 -22
  51. package/dist/components/ui/DirectoryPicker.js +8 -8
  52. package/dist/components/ui/Dropdown.js +89 -87
  53. package/dist/components/ui/FeedbackIndicator.js +57 -57
  54. package/dist/components/ui/FileOpenPicker.js +37 -37
  55. package/dist/components/ui/FileSavePicker.js +41 -41
  56. package/dist/components/ui/FloatingWindow.js +266 -261
  57. package/dist/components/ui/Form.js +76 -76
  58. package/dist/components/ui/HighlightBlock.js +14 -14
  59. package/dist/components/ui/Input.js +106 -109
  60. package/dist/components/ui/Pagination.js +86 -86
  61. package/dist/components/ui/Popover.d.ts +33 -0
  62. package/dist/components/ui/Popover.js +133 -0
  63. package/dist/components/ui/ProcessingIndicator.js +344 -345
  64. package/dist/components/ui/Progress.js +94 -97
  65. package/dist/components/ui/QuoteBlock.js +25 -25
  66. package/dist/components/ui/Radio.js +91 -91
  67. package/dist/components/ui/SegmentedControl.js +24 -24
  68. package/dist/components/ui/Stepper.js +68 -60
  69. package/dist/components/ui/Switch.js +25 -25
  70. package/dist/components/ui/Tabs.js +99 -87
  71. package/dist/components/ui/Tag.js +12 -9
  72. package/dist/components/ui/Tooltip.js +30 -30
  73. package/dist/components/ui/floatingPresence.d.ts +7 -0
  74. package/dist/components/ui/floatingPresence.js +80 -39
  75. package/dist/components/ui/index.d.ts +2 -1
  76. package/dist/components/ui/picker/DirectoryFavorites.js +27 -27
  77. package/dist/components/ui/picker/PickerBase.js +107 -107
  78. package/dist/context/NotificationContext.js +4 -4
  79. package/dist/context/ThemeContext.js +71 -70
  80. package/dist/floe.css +205 -43
  81. package/dist/full.js +650 -652
  82. package/dist/language.css +320 -0
  83. package/dist/primitives.css +23 -17
  84. package/dist/standalone.css +1 -0
  85. package/dist/styles/themes/classicSemanticTokens.d.ts +122 -122
  86. package/dist/styles/themes/classicSemanticTokens.js +140 -138
  87. package/dist/styles/themes/index.d.ts +3 -1
  88. package/dist/styles/themes/index.js +10 -10
  89. package/dist/styles/themes/presets.d.ts +2 -2
  90. package/dist/styles/themes/presets.js +34 -34
  91. package/dist/styles/tokens.d.ts +152 -68
  92. package/dist/styles/tokens.js +87 -49
  93. package/dist/styles.css +1 -1
  94. package/dist/surface.css +161 -116
  95. package/dist/themes/dark.css +64 -64
  96. package/dist/themes/light.css +64 -64
  97. package/dist/ui.css +171 -255
  98. package/dist/ui.js +176 -178
  99. package/dist/utils/hotInteraction.d.ts +7 -0
  100. package/dist/utils/hotInteraction.js +12 -12
  101. package/dist/widgets/TerminalWidget.js +28 -28
  102. package/dist/workbench-composition.css +15 -15
  103. package/package.json +1 -1
package/dist/ui.css CHANGED
@@ -332,6 +332,14 @@
332
332
  animation: processing-bar 1s ease-in-out infinite;
333
333
  }
334
334
 
335
+ /* The spinning conic gradient paints on its own compositing layer, which the
336
+ parent's rounded `overflow: hidden` does not reliably clip — any uncovered
337
+ corner shows up as a stray hairline outside the pill. Clip the ring itself
338
+ so only the intended 1px edge can ever render. */
339
+ .processing-gradient-border {
340
+ clip-path: inset(0 round 9999px);
341
+ }
342
+
335
343
  .processing-gradient-spin {
336
344
  animation: processing-gradient-spin 2s linear infinite;
337
345
  }
@@ -637,53 +645,46 @@
637
645
  ============================================================================= */
638
646
 
639
647
  .highlight-block {
640
- --hb-accent: var(--primary);
641
- --hb-border: color-mix(in srgb, var(--hb-accent) 34%, var(--border));
642
- --hb-header-bg: color-mix(in srgb, var(--hb-accent) 18%, var(--card));
643
- --hb-content-bg: color-mix(in srgb, var(--hb-accent) 10%, var(--card));
644
- --hb-title: color-mix(in srgb, var(--hb-accent) 78%, var(--foreground));
648
+ --hb-accent: var(--floe-ink-quiet);
649
+ --hb-ink: var(--floe-ink);
645
650
 
646
- border-radius: 6px;
651
+ border-radius: var(--floe-radius-group);
647
652
  overflow: hidden;
648
- border: 1px solid var(--hb-border);
653
+ border: 1px solid transparent;
654
+ background-color: color-mix(in srgb, var(--hb-accent) 7%, transparent);
649
655
  }
650
656
 
651
657
  .highlight-block-header {
652
658
  display: flex;
653
659
  align-items: center;
654
- gap: 8px;
655
- padding: 8px 12px 8px 14px;
656
- background: var(--hb-header-bg);
657
- border-left: 3px solid var(--hb-accent);
658
- margin-left: -1px;
660
+ gap: 0.5rem;
661
+ padding: 0.4375rem 0.875rem 0;
662
+ color: var(--hb-accent);
659
663
  }
660
664
 
661
665
  .highlight-block-icon {
662
666
  flex-shrink: 0;
663
- opacity: 0.95;
664
- color: var(--hb-title);
667
+ color: var(--hb-accent);
665
668
  }
666
669
 
667
670
  .highlight-block-title {
668
- font-size: 11px;
671
+ font-size: var(--floe-type-caption);
672
+ line-height: var(--floe-line-caption);
669
673
  font-weight: 600;
670
674
  text-transform: uppercase;
671
- letter-spacing: 0.04em;
672
- color: var(--hb-title);
675
+ letter-spacing: 0.06em;
676
+ color: var(--hb-accent);
673
677
  }
674
678
 
675
679
  .highlight-block-content {
676
- padding: 10px 14px 12px 17px;
677
- background: var(--hb-content-bg);
678
- border-left: 3px solid transparent;
679
- margin-left: -1px;
680
- font-size: 12px;
681
- line-height: 1.65;
682
- color: color-mix(in srgb, var(--foreground) 90%, transparent);
680
+ padding: 0.375rem 0.875rem 0.6875rem;
681
+ font-size: var(--floe-type-supporting);
682
+ line-height: var(--floe-line-body);
683
+ color: var(--hb-ink);
683
684
  }
684
685
 
685
686
  .highlight-block-content > p {
686
- margin-bottom: 6px;
687
+ margin-bottom: 0.375rem;
687
688
  }
688
689
  .highlight-block-content > p:last-child {
689
690
  margin-bottom: 0;
@@ -691,8 +692,8 @@
691
692
 
692
693
  .highlight-block-content > ul,
693
694
  .highlight-block-content > ol {
694
- padding-left: 16px;
695
- margin-bottom: 6px;
695
+ padding-left: 1rem;
696
+ margin-bottom: 0.375rem;
696
697
  }
697
698
 
698
699
  .highlight-block-content > ul {
@@ -702,6 +703,10 @@
702
703
  list-style-type: decimal;
703
704
  }
704
705
 
706
+ /* Semantic variants tint the same quiet well rather than filling a block.
707
+ * Each callout reads its own `--highlight-block-*-accent`, which every preset
708
+ * tunes for its own planes — borrowing the shared status colors here would
709
+ * override that tuning and put a 4.5:1 status fill on a 7% wash. */
705
710
  .highlight-block-info {
706
711
  --hb-accent: var(--highlight-block-info-accent);
707
712
  }
@@ -731,11 +736,15 @@
731
736
  ============================================================================= */
732
737
 
733
738
  .floe-segmented-control {
734
- --segmented-control-bg: color-mix(in srgb, var(--muted) 74%, var(--background));
735
- --segmented-control-border: color-mix(in srgb, var(--border) 82%, transparent);
736
- --segmented-control-item-color: var(--muted-foreground);
737
- --segmented-control-item-hover-bg: color-mix(in srgb, var(--background) 74%, var(--muted) 26%);
738
- --segmented-control-item-hover-color: var(--foreground);
739
+ /* The rail is a well: recessed, one hairline, no accent. The selected
740
+ * segment is the one opaque thing inside it, in the semantic pair, because
741
+ * a translucent tint cannot reach the 3:1 that marks a selection. Relief
742
+ * would be a second, weaker way of saying the same thing, so it stays off. */
743
+ --segmented-control-bg: var(--floe-well);
744
+ --segmented-control-border: var(--floe-line);
745
+ --segmented-control-item-color: var(--floe-ink-soft);
746
+ --segmented-control-item-hover-bg: var(--floe-state-hover);
747
+ --segmented-control-item-hover-color: var(--floe-ink);
739
748
  --segmented-control-item-active-bg: var(--primary);
740
749
  --segmented-control-item-active-border: var(--primary);
741
750
  --segmented-control-item-active-color: var(--primary-foreground);
@@ -745,16 +754,6 @@
745
754
  border-color: var(--segmented-control-border);
746
755
  }
747
756
 
748
- .dark .floe-segmented-control {
749
- --segmented-control-bg: color-mix(in srgb, var(--muted) 56%, var(--background) 44%);
750
- --segmented-control-border: color-mix(in srgb, var(--border) 78%, var(--foreground) 22%);
751
- --segmented-control-item-hover-bg: color-mix(
752
- in srgb,
753
- var(--foreground) 8%,
754
- var(--background) 92%
755
- );
756
- }
757
-
758
757
  .floe-segmented-control__item {
759
758
  border-color: transparent;
760
759
  color: var(--segmented-control-item-color);
@@ -765,7 +764,7 @@
765
764
  color: var(--segmented-control-item-hover-color);
766
765
  }
767
766
 
768
- .floe-segmented-control__item--active {
767
+ .floe-segmented-control__item[aria-checked='true'] {
769
768
  border-color: var(--segmented-control-item-active-border);
770
769
  background-color: var(--segmented-control-item-active-bg);
771
770
  color: var(--segmented-control-item-active-color);
@@ -773,179 +772,82 @@
773
772
  }
774
773
 
775
774
  /* =============================================================================
776
- Tag - Professional metadata labels
777
- ============================================================================= */
778
-
779
- :root,
780
- .light {
781
- --tag-solid-ink-strong: var(--primary-foreground);
782
- --tag-soft-surface-base: white;
783
- --tag-soft-line-base: white;
784
- --tag-soft-ink-base: var(--foreground);
785
- --tag-soft-surface-strength: 84%;
786
- --tag-soft-line-strength: 68%;
787
- --tag-soft-ink-strength: 74%;
788
-
789
- --tag-neutral-solid-surface: color-mix(in srgb, var(--foreground) 86%, var(--muted));
790
- --tag-neutral-solid-line: color-mix(in srgb, var(--foreground) 72%, var(--border));
791
- --tag-neutral-accent: color-mix(in srgb, var(--foreground) 44%, var(--muted-foreground));
792
-
793
- --tag-primary-solid-surface: color-mix(in srgb, var(--info) 78%, var(--foreground));
794
- --tag-primary-solid-line: color-mix(in srgb, var(--info) 88%, var(--foreground));
795
- --tag-primary-accent: color-mix(in srgb, var(--info) 74%, var(--foreground));
796
-
797
- --tag-success-solid-surface: color-mix(in srgb, var(--success) 72%, var(--foreground));
798
- --tag-success-solid-line: color-mix(in srgb, var(--success) 88%, var(--foreground));
799
- --tag-success-accent: color-mix(in srgb, var(--success) 70%, var(--foreground));
800
-
801
- --tag-warning-solid-surface: color-mix(in srgb, var(--warning) 78%, var(--foreground));
802
- --tag-warning-solid-line: color-mix(in srgb, var(--warning) 92%, var(--foreground));
803
- --tag-warning-accent: color-mix(in srgb, var(--warning) 68%, var(--foreground));
804
-
805
- --tag-error-solid-surface: color-mix(in srgb, var(--error) 70%, var(--foreground));
806
- --tag-error-solid-line: color-mix(in srgb, var(--error) 86%, var(--foreground));
807
- --tag-error-accent: color-mix(in srgb, var(--error) 70%, var(--foreground));
775
+ Tag - metadata, not a badge of honour
808
776
 
809
- --tag-info-solid-surface: color-mix(in srgb, var(--info) 66%, var(--foreground));
810
- --tag-info-solid-line: color-mix(in srgb, var(--info) 78%, var(--foreground));
811
- --tag-info-accent: color-mix(in srgb, var(--info) 62%, var(--foreground));
812
- }
813
-
814
- .dark {
815
- --tag-solid-ink-strong: var(--foreground);
816
- --tag-soft-surface-base: transparent;
817
- --tag-soft-line-base: transparent;
818
- --tag-soft-ink-base: var(--foreground);
819
- --tag-soft-surface-strength: 88%;
820
- --tag-soft-line-strength: 76%;
821
- --tag-soft-ink-strength: 82%;
822
-
823
- --tag-neutral-solid-surface: color-mix(in srgb, var(--foreground) 20%, var(--background));
824
- --tag-neutral-solid-line: color-mix(in srgb, var(--foreground) 28%, var(--border));
825
- --tag-neutral-accent: color-mix(in srgb, var(--foreground) 58%, var(--muted-foreground));
826
-
827
- --tag-primary-solid-surface: color-mix(in srgb, var(--info) 54%, var(--background));
828
- --tag-primary-solid-line: color-mix(in srgb, var(--info) 70%, var(--border));
829
- --tag-primary-accent: color-mix(in srgb, var(--info) 80%, white 20%);
830
-
831
- --tag-success-solid-surface: color-mix(in srgb, var(--success) 52%, var(--background));
832
- --tag-success-solid-line: color-mix(in srgb, var(--success) 68%, var(--border));
833
- --tag-success-accent: color-mix(in srgb, var(--success) 80%, white 20%);
834
-
835
- --tag-warning-solid-surface: color-mix(in srgb, var(--warning) 62%, var(--background));
836
- --tag-warning-solid-line: color-mix(in srgb, var(--warning) 78%, var(--border));
837
- --tag-warning-accent: color-mix(in srgb, var(--warning) 80%, white 20%);
838
-
839
- --tag-error-solid-surface: color-mix(in srgb, var(--error) 48%, var(--background));
840
- --tag-error-solid-line: color-mix(in srgb, var(--error) 64%, var(--border));
841
- --tag-error-accent: color-mix(in srgb, var(--error) 80%, white 20%);
842
-
843
- --tag-info-solid-surface: color-mix(in srgb, var(--info) 40%, var(--background));
844
- --tag-info-solid-line: color-mix(in srgb, var(--info) 54%, var(--border));
845
- --tag-info-accent: color-mix(in srgb, var(--info) 72%, white 28%);
846
- }
777
+ One recipe per tone. The hue only ever arrives as a translucent wash of the
778
+ semantic color over the plane it sits on, plus the ink mixed with the same
779
+ color, so a tag works on a card, on a well and in dark mode without a
780
+ second ladder. There is no solid color block and no white-on-color text:
781
+ status color should read as a whisper of meaning, not a sticker.
782
+ ============================================================================= */
847
783
 
784
+ /* Two tones, two gestures. `soft` is an outline: no fill, a hairline and
785
+ * accent-tinted ink, for metadata that rides along with content. `solid` is
786
+ * a wash: the accent fills the chip so state reads at a glance in a list.
787
+ * Neither paints a colour block, so status stays a whisper of meaning. */
848
788
  .floe-tag {
849
- --tag-solid-surface: var(--tag-neutral-solid-surface);
850
- --tag-solid-line: var(--tag-neutral-solid-line);
851
- --tag-solid-ink: var(--tag-solid-ink-strong);
852
- --tag-soft-accent: var(--tag-neutral-accent);
853
- --tag-surface: var(--tag-solid-surface);
854
- --tag-line: var(--tag-solid-line);
855
- --tag-ink: var(--tag-solid-ink);
789
+ --tag-accent: var(--floe-ink-soft);
856
790
 
857
791
  display: inline-flex;
858
792
  align-items: center;
859
- gap: 6px;
793
+ gap: 0.375rem;
860
794
  max-width: 100%;
861
795
  min-width: 0;
862
796
  white-space: nowrap;
863
- border-radius: 8px;
864
- border: 1px solid var(--tag-line);
865
- background-color: var(--tag-surface);
866
- color: var(--tag-ink);
797
+ border-radius: var(--floe-radius-sm);
798
+ border: 1px solid transparent;
799
+ color: color-mix(in srgb, var(--tag-accent) 76%, var(--floe-ink));
867
800
  font-weight: 600;
868
- letter-spacing: 0.015em;
801
+ letter-spacing: 0.005em;
869
802
  }
870
803
 
804
+ /* Fill and edge belong to the surface layer, which paints every badge part. */
871
805
  .floe-tag--solid {
872
- --tag-surface: var(--tag-solid-surface);
873
- --tag-line: var(--tag-solid-line);
874
- --tag-ink: var(--tag-solid-ink);
806
+ color: color-mix(in srgb, var(--tag-accent) 88%, var(--floe-ink));
875
807
  }
876
808
 
877
809
  .floe-tag--neutral {
878
- --tag-solid-surface: var(--tag-neutral-solid-surface);
879
- --tag-solid-line: var(--tag-neutral-solid-line);
880
- --tag-soft-accent: var(--tag-neutral-accent);
810
+ --tag-accent: var(--floe-ink-soft);
881
811
  }
882
812
 
883
813
  .floe-tag--primary {
884
- --tag-solid-surface: var(--tag-primary-solid-surface);
885
- --tag-solid-line: var(--tag-primary-solid-line);
886
- --tag-soft-accent: var(--tag-primary-accent);
814
+ --tag-accent: var(--floe-accent-ink);
887
815
  }
888
816
 
889
817
  .floe-tag--success {
890
- --tag-solid-surface: var(--tag-success-solid-surface);
891
- --tag-solid-line: var(--tag-success-solid-line);
892
- --tag-soft-accent: var(--tag-success-accent);
818
+ --tag-accent: var(--success);
893
819
  }
894
820
 
895
821
  .floe-tag--warning {
896
- --tag-solid-surface: var(--tag-warning-solid-surface);
897
- --tag-solid-line: var(--tag-warning-solid-line);
898
- --tag-soft-accent: var(--tag-warning-accent);
822
+ --tag-accent: var(--warning);
899
823
  }
900
824
 
901
825
  .floe-tag--error {
902
- --tag-solid-surface: var(--tag-error-solid-surface);
903
- --tag-solid-line: var(--tag-error-solid-line);
904
- --tag-soft-accent: var(--tag-error-accent);
826
+ --tag-accent: var(--error);
905
827
  }
906
828
 
907
829
  .floe-tag--info {
908
- --tag-solid-surface: var(--tag-info-solid-surface);
909
- --tag-solid-line: var(--tag-info-solid-line);
910
- --tag-soft-accent: var(--tag-info-accent);
911
- }
912
-
913
- .floe-tag--soft {
914
- --tag-surface: color-mix(
915
- in srgb,
916
- var(--tag-soft-surface-base) var(--tag-soft-surface-strength),
917
- var(--tag-soft-accent)
918
- );
919
- --tag-line: color-mix(
920
- in srgb,
921
- var(--tag-soft-line-base) var(--tag-soft-line-strength),
922
- var(--tag-soft-accent)
923
- );
924
- --tag-ink: color-mix(
925
- in srgb,
926
- var(--tag-soft-ink-base) var(--tag-soft-ink-strength),
927
- var(--tag-soft-accent)
928
- );
830
+ --tag-accent: var(--info);
929
831
  }
930
832
 
931
833
  .floe-tag--sm {
932
- min-height: 18px;
933
- padding: 0 7px;
934
- font-size: 10px;
834
+ min-height: 1.125rem;
835
+ padding: 0 0.375rem;
836
+ font-size: var(--floe-type-caption);
935
837
  line-height: 1;
936
838
  }
937
839
 
938
840
  .floe-tag--md {
939
- min-height: 22px;
940
- padding: 0 8px;
941
- font-size: 11px;
841
+ min-height: 1.375rem;
842
+ padding: 0 0.4375rem;
843
+ font-size: var(--floe-type-caption);
942
844
  line-height: 1;
943
845
  }
944
846
 
945
847
  .floe-tag--lg {
946
- min-height: 26px;
947
- padding: 0 10px;
948
- font-size: 12px;
848
+ min-height: 1.625rem;
849
+ padding: 0 0.5625rem;
850
+ font-size: var(--floe-type-supporting);
949
851
  line-height: 1;
950
852
  }
951
853
 
@@ -960,8 +862,8 @@
960
862
  }
961
863
 
962
864
  .floe-tag__dot {
963
- width: 6px;
964
- height: 6px;
865
+ width: 5px;
866
+ height: 5px;
965
867
  flex: none;
966
868
  border-radius: 999px;
967
869
  background: currentColor;
@@ -982,23 +884,29 @@
982
884
  width: 13px;
983
885
  height: 13px;
984
886
  }
985
-
986
887
  /* =============================================================================
987
- Charts - Professional Data Visualization
888
+ Charts — data as ink, not as decoration
889
+
890
+ A chart is a reading surface. Grid lines are the quietest rule in the
891
+ ladder, the axis is tiny caps in the ghost ink, and the series colors are
892
+ the only saturated thing on the plane. Nothing glows, nothing casts a
893
+ shadow except the tooltip, and every transient reads on the motion family.
988
894
  ============================================================================= */
989
895
 
990
896
  .chart-container {
991
897
  width: 100%;
992
898
  position: relative;
899
+ color: var(--floe-ink);
993
900
  }
994
901
 
995
902
  .chart-title {
996
- font-size: 11px;
903
+ font-size: var(--floe-type-caption);
997
904
  font-weight: 600;
998
- color: var(--foreground);
999
- margin-bottom: 12px;
905
+ line-height: var(--floe-line-caption);
906
+ color: var(--floe-ink-soft);
907
+ margin-bottom: var(--floe-gap-group);
908
+ letter-spacing: var(--floe-tracking-caps, 0.06em);
1000
909
  text-transform: uppercase;
1001
- letter-spacing: 0.04em;
1002
910
  }
1003
911
 
1004
912
  .chart-svg {
@@ -1006,33 +914,37 @@
1006
914
  overflow: visible;
1007
915
  }
1008
916
 
1009
- /* Grid lines */
917
+ /* Grid — one hairline, solid. Dashes turn a grid into visual noise. */
1010
918
  .chart-grid-line {
1011
- stroke: var(--border);
919
+ stroke: var(--floe-line-quiet);
1012
920
  stroke-width: 1;
1013
- stroke-dasharray: 4 4;
921
+ stroke-dasharray: none;
1014
922
  }
1015
923
 
1016
- /* Axis labels */
1017
924
  .chart-axis-label {
1018
- font-size: 10px;
1019
- fill: var(--muted-foreground);
925
+ font-size: var(--floe-type-caption);
926
+ fill: var(--floe-ink-ghost);
1020
927
  font-family: var(--font-sans);
928
+ font-variant-numeric: tabular-nums;
929
+ letter-spacing: 0.01em;
1021
930
  }
1022
931
 
1023
932
  /* Line chart */
1024
933
  .chart-line {
1025
- transition: stroke-dashoffset 0.8s ease-out;
934
+ stroke-linecap: round;
935
+ stroke-linejoin: round;
936
+ transition: stroke-dashoffset var(--floe-duration-slow) var(--floe-ease-out);
1026
937
  }
1027
938
 
1028
939
  .chart-area {
1029
- transition: opacity 0.6s ease-out;
940
+ transition: opacity var(--floe-duration-slow) var(--floe-ease-out);
1030
941
  }
1031
942
 
1032
943
  .chart-point {
944
+ stroke-width: 2;
1033
945
  transition:
1034
- opacity 0.3s ease,
1035
- r 0.15s ease;
946
+ opacity var(--floe-duration-fast) var(--floe-ease-out),
947
+ r var(--floe-duration-fast) var(--floe-ease-out);
1036
948
  cursor: pointer;
1037
949
  }
1038
950
 
@@ -1040,42 +952,42 @@
1040
952
  r: 6;
1041
953
  }
1042
954
 
1043
- /* Crosshair */
955
+ /* Crosshair — a quiet accent, not a primary-colored rule */
1044
956
  .chart-crosshair {
1045
- stroke: var(--primary);
957
+ stroke: var(--floe-accent-line);
1046
958
  stroke-width: 1;
1047
- stroke-dasharray: 4 2;
1048
- opacity: 0.6;
959
+ stroke-dasharray: none;
1049
960
  pointer-events: none;
1050
961
  }
1051
962
 
1052
963
  .chart-crosshair-point {
1053
- stroke: var(--background);
964
+ stroke: var(--floe-plane-float);
1054
965
  stroke-width: 2;
1055
966
  pointer-events: none;
1056
967
  }
1057
968
 
1058
- /* Tooltip */
969
+ /* Tooltip — the one floating object in a chart */
1059
970
  .chart-tooltip-bg {
1060
- fill: var(--popover);
1061
- stroke: var(--border);
971
+ fill: var(--floe-plane-float);
972
+ stroke: var(--floe-line);
1062
973
  stroke-width: 1;
1063
- filter: drop-shadow(0 2px 4px color-mix(in srgb, var(--foreground) 12%, transparent));
974
+ filter: drop-shadow(0 6px 18px color-mix(in srgb, var(--floe-ink) 14%, transparent));
1064
975
  pointer-events: none;
1065
976
  }
1066
977
 
1067
978
  .chart-tooltip-label {
1068
- font-size: 9px;
979
+ font-size: var(--floe-type-caption);
1069
980
  font-weight: 600;
1070
- fill: var(--foreground);
981
+ fill: var(--floe-ink-soft);
1071
982
  font-family: var(--font-sans);
1072
983
  pointer-events: none;
1073
984
  }
1074
985
 
1075
986
  .chart-tooltip-value {
1076
- font-size: 8px;
1077
- fill: var(--muted-foreground);
987
+ font-size: var(--floe-type-caption);
988
+ fill: var(--floe-ink);
1078
989
  font-family: var(--font-mono);
990
+ font-variant-numeric: tabular-nums;
1079
991
  pointer-events: none;
1080
992
  }
1081
993
 
@@ -1085,19 +997,22 @@
1085
997
 
1086
998
  /* Bar chart */
1087
999
  .chart-bar {
1088
- transition: opacity 0.15s ease;
1000
+ transition:
1001
+ opacity var(--floe-duration-fast) var(--floe-ease-out),
1002
+ filter var(--floe-duration-fast) var(--floe-ease-out);
1089
1003
  cursor: pointer;
1090
1004
  }
1091
1005
 
1092
1006
  .chart-bar:hover {
1093
- filter: brightness(1.1);
1007
+ filter: brightness(1.06);
1094
1008
  }
1095
1009
 
1096
1010
  .chart-bar-value {
1097
- font-size: 10px;
1098
- fill: var(--foreground);
1099
- font-weight: 500;
1011
+ font-size: var(--floe-type-caption);
1012
+ fill: var(--floe-ink-soft);
1013
+ font-weight: 600;
1100
1014
  font-family: var(--font-mono);
1015
+ font-variant-numeric: tabular-nums;
1101
1016
  }
1102
1017
 
1103
1018
  /* Pie chart */
@@ -1112,7 +1027,7 @@
1112
1027
  flex-wrap: wrap;
1113
1028
  align-items: center;
1114
1029
  justify-content: center;
1115
- gap: 24px;
1030
+ gap: var(--floe-gap-section);
1116
1031
  }
1117
1032
 
1118
1033
  .chart-pie-svg {
@@ -1121,69 +1036,74 @@
1121
1036
 
1122
1037
  .chart-pie-slice {
1123
1038
  transition:
1124
- transform 0.15s ease,
1125
- filter 0.15s ease;
1039
+ transform var(--floe-duration-fast) var(--floe-ease-out),
1040
+ filter var(--floe-duration-fast) var(--floe-ease-out);
1126
1041
  transform-origin: center;
1127
1042
  cursor: pointer;
1128
1043
  }
1129
1044
 
1130
1045
  .chart-pie-slice:hover {
1131
- transform: scale(1.03);
1132
- filter: brightness(1.1);
1046
+ transform: scale(1.02);
1047
+ filter: brightness(1.06);
1133
1048
  }
1134
1049
 
1135
1050
  .chart-pie-center-label {
1136
- font-size: 18px;
1137
- font-weight: 700;
1138
- fill: var(--foreground);
1051
+ font-size: var(--floe-type-heading);
1052
+ font-weight: 600;
1053
+ fill: var(--floe-ink);
1139
1054
  font-family: var(--font-sans);
1055
+ font-variant-numeric: tabular-nums;
1140
1056
  }
1141
1057
 
1142
1058
  .chart-pie-center-sublabel {
1143
- font-size: 8px;
1144
- fill: var(--muted-foreground);
1059
+ font-size: var(--floe-type-caption);
1060
+ fill: var(--floe-ink-ghost);
1145
1061
  font-family: var(--font-sans);
1062
+ letter-spacing: 0.04em;
1063
+ text-transform: uppercase;
1146
1064
  }
1147
1065
 
1148
1066
  .chart-pie-legend {
1149
1067
  display: flex;
1150
1068
  flex-direction: column;
1151
- gap: 8px;
1069
+ gap: var(--floe-gap-control);
1152
1070
  }
1153
1071
 
1154
- /* Legend */
1072
+ /* Legend — swatch, label, value: one row rhythm */
1155
1073
  .chart-legend {
1156
1074
  display: flex;
1157
1075
  flex-wrap: wrap;
1158
- gap: 12px;
1159
- margin-top: 12px;
1076
+ gap: var(--floe-gap-group);
1077
+ margin-top: var(--floe-gap-group);
1160
1078
  justify-content: center;
1161
1079
  }
1162
1080
 
1163
1081
  .chart-legend-item {
1164
1082
  display: flex;
1165
1083
  align-items: center;
1166
- gap: 6px;
1084
+ gap: var(--floe-gap-inline);
1167
1085
  }
1168
1086
 
1169
1087
  .chart-legend-color {
1170
- width: 10px;
1171
- height: 10px;
1172
- border-radius: 2px;
1088
+ width: 8px;
1089
+ height: 8px;
1090
+ border-radius: var(--floe-radius-xs);
1173
1091
  flex-shrink: 0;
1174
1092
  }
1175
1093
 
1176
1094
  .chart-legend-label {
1177
- font-size: 11px;
1178
- color: var(--muted-foreground);
1095
+ font-size: var(--floe-type-supporting);
1096
+ color: var(--floe-ink-soft);
1097
+ line-height: var(--floe-line-caption);
1179
1098
  }
1180
1099
 
1181
1100
  .chart-legend-value {
1182
- font-size: 11px;
1183
- font-weight: 500;
1184
- color: var(--foreground);
1101
+ font-size: var(--floe-type-supporting);
1102
+ font-weight: 600;
1103
+ color: var(--floe-ink);
1185
1104
  font-family: var(--font-mono);
1186
- margin-left: 4px;
1105
+ font-variant-numeric: tabular-nums;
1106
+ margin-left: var(--floe-gap-inline);
1187
1107
  }
1188
1108
 
1189
1109
  /* Monitoring chart */
@@ -1197,14 +1117,14 @@
1197
1117
  display: flex;
1198
1118
  align-items: center;
1199
1119
  justify-content: space-between;
1200
- gap: 8px;
1201
- margin-bottom: 8px;
1120
+ gap: var(--floe-gap-control);
1121
+ margin-bottom: var(--floe-gap-control);
1202
1122
  }
1203
1123
 
1204
1124
  .chart-monitoring-heading {
1205
1125
  display: flex;
1206
1126
  align-items: center;
1207
- gap: 8px;
1127
+ gap: var(--floe-gap-control);
1208
1128
  min-width: 0;
1209
1129
  }
1210
1130
 
@@ -1217,9 +1137,9 @@
1217
1137
  flex-shrink: 0;
1218
1138
  max-width: 100%;
1219
1139
  overflow-wrap: anywhere;
1220
- font-size: 11px;
1140
+ font-size: var(--floe-type-caption);
1221
1141
  font-variant-numeric: tabular-nums;
1222
- color: var(--muted-foreground);
1142
+ color: var(--floe-ink-soft);
1223
1143
  text-align: end;
1224
1144
  }
1225
1145
 
@@ -1230,30 +1150,30 @@
1230
1150
  .chart-monitoring-status {
1231
1151
  display: flex;
1232
1152
  align-items: center;
1233
- gap: 6px;
1234
- font-size: 10px;
1235
- color: var(--muted-foreground);
1153
+ gap: var(--floe-gap-inline);
1154
+ font-size: var(--floe-type-caption);
1155
+ color: var(--floe-ink-ghost);
1236
1156
  text-transform: uppercase;
1237
- letter-spacing: 0.05em;
1157
+ letter-spacing: 0.06em;
1238
1158
  }
1239
1159
 
1240
1160
  .chart-monitoring-dot {
1241
1161
  width: 6px;
1242
1162
  height: 6px;
1243
- border-radius: 50%;
1163
+ border-radius: var(--floe-radius-xs);
1244
1164
  background: var(--success);
1245
- animation: chart-monitoring-pulse 1.5s ease-in-out infinite;
1165
+ animation: chart-monitoring-pulse 2.4s var(--floe-ease-in-out) infinite;
1246
1166
  }
1247
1167
 
1248
1168
  @keyframes chart-monitoring-pulse {
1249
1169
  0%,
1250
1170
  100% {
1251
1171
  opacity: 1;
1252
- box-shadow: 0 0 0 0 color-mix(in srgb, var(--success) 50%, transparent);
1172
+ box-shadow: 0 0 0 0 color-mix(in srgb, var(--success) 38%, transparent);
1253
1173
  }
1254
1174
  50% {
1255
- opacity: 0.8;
1256
- box-shadow: 0 0 0 4px color-mix(in srgb, var(--success) 0%, transparent);
1175
+ opacity: 0.72;
1176
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 0%, transparent);
1257
1177
  }
1258
1178
  }
1259
1179
 
@@ -1270,19 +1190,15 @@
1270
1190
  }
1271
1191
 
1272
1192
  .chart-legend {
1273
- gap: 8px;
1193
+ gap: var(--floe-gap-control);
1274
1194
  }
1275
1195
 
1276
1196
  .chart-legend-item {
1277
- gap: 4px;
1278
- }
1279
-
1280
- .chart-legend-label,
1281
- .chart-legend-value {
1282
- font-size: 10px;
1197
+ gap: var(--floe-gap-inline);
1283
1198
  }
1284
1199
  }
1285
1200
 
1201
+
1286
1202
  /* ============================================
1287
1203
  Mobile Keyboard
1288
1204
  ============================================ */