fokus-styles 2.3.0 → 2.5.0

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 (101) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/css/components.css +583 -83
  3. package/dist/css/components.css.map +1 -1
  4. package/dist/css/components.min.css +1 -1
  5. package/dist/css/components.min.css.map +1 -1
  6. package/dist/css/fokus-components.css +583 -83
  7. package/dist/css/fokus-components.css.map +1 -1
  8. package/dist/css/fokus-components.min.css +1 -1
  9. package/dist/css/fokus-components.min.css.map +1 -1
  10. package/dist/css/fokus-core.css +22 -0
  11. package/dist/css/fokus-core.css.map +1 -1
  12. package/dist/css/fokus-core.min.css +1 -1
  13. package/dist/css/fokus-core.min.css.map +1 -1
  14. package/dist/css/fokus-dark.css +10 -0
  15. package/dist/css/fokus-dark.css.map +1 -1
  16. package/dist/css/fokus-dark.min.css +1 -1
  17. package/dist/css/fokus-dark.min.css.map +1 -1
  18. package/dist/css/fokus-rtl.css +9166 -0
  19. package/dist/css/fokus-rtl.css.map +1 -0
  20. package/dist/css/fokus-rtl.min.css +2 -0
  21. package/dist/css/fokus-rtl.min.css.map +1 -0
  22. package/dist/css/fokus-utilities.css +158 -0
  23. package/dist/css/fokus-utilities.css.map +1 -1
  24. package/dist/css/fokus-utilities.min.css +1 -1
  25. package/dist/css/fokus-utilities.min.css.map +1 -1
  26. package/dist/css/fokus.css +1018 -258
  27. package/dist/css/fokus.css.map +1 -1
  28. package/dist/css/fokus.min.css +1 -1
  29. package/dist/css/fokus.min.css.map +1 -1
  30. package/dist/css/forms.css +322 -176
  31. package/dist/css/forms.css.map +1 -1
  32. package/dist/css/forms.min.css +1 -1
  33. package/dist/css/forms.min.css.map +1 -1
  34. package/dist/css/helpers.css +158 -0
  35. package/dist/css/helpers.css.map +1 -1
  36. package/dist/css/helpers.min.css +1 -1
  37. package/dist/css/helpers.min.css.map +1 -1
  38. package/dist/css/layout.css +22 -0
  39. package/dist/css/layout.css.map +1 -1
  40. package/dist/css/layout.min.css +1 -1
  41. package/dist/css/layout.min.css.map +1 -1
  42. package/dist/js/fokus.js +270 -25
  43. package/dist/js/fokus.js.map +2 -2
  44. package/dist/js/fokus.min.js +18 -18
  45. package/dist/js/fokus.min.js.map +3 -3
  46. package/docs/components/alert.md +69 -24
  47. package/docs/components/badge.md +23 -4
  48. package/docs/components/checkbox.md +16 -3
  49. package/docs/components/popover.md +20 -7
  50. package/docs/components/radio.md +11 -1
  51. package/docs/components/responsive.md +19 -0
  52. package/docs/components/switch.md +30 -8
  53. package/docs/components/tag.md +19 -4
  54. package/docs/components/toast.md +72 -59
  55. package/docs/components/tooltip.md +38 -2
  56. package/docs/guides/accessibility.md +7 -0
  57. package/docs/guides/rtl-and-system-preferences.md +28 -0
  58. package/docs/prompts/prompt-plan.md +4 -4
  59. package/docs/reference/accessibility-matrix.md +7 -7
  60. package/docs/reference/contrast-report.md +4 -0
  61. package/docs/reference/definitions.md +5 -1
  62. package/docs/reference/design-tokens.md +14 -0
  63. package/docs/reference/size-baseline.json +13 -13
  64. package/mockup/assets/example-theme.css +11 -0
  65. package/mockup/assets/showcase-contracts.js +6 -6
  66. package/mockup/examples/alerts.html +105 -31
  67. package/mockup/examples/badges-alerts.html +91 -59
  68. package/mockup/examples/check-radio-switch.html +575 -99
  69. package/mockup/examples/popover.html +81 -0
  70. package/mockup/examples/tag.html +97 -87
  71. package/mockup/examples/toast.html +113 -0
  72. package/mockup/examples/tooltip.html +68 -0
  73. package/mockup/forms.html +1 -1
  74. package/mockup/overlays-commands.html +2 -2
  75. package/package.json +2 -1
  76. package/packages/fokus-components/scss/components/_alerts.scss +128 -6
  77. package/packages/fokus-components/scss/components/_badges.scss +26 -10
  78. package/packages/fokus-components/scss/components/_index.scss +1 -0
  79. package/packages/fokus-components/scss/components/_popover.scss +131 -21
  80. package/packages/fokus-components/scss/components/_responsive.scss +23 -0
  81. package/packages/fokus-components/scss/components/_tag.scss +37 -14
  82. package/packages/fokus-components/scss/components/_toasts.scss +156 -11
  83. package/packages/fokus-components/scss/components/_tooltips.scss +70 -18
  84. package/packages/fokus-components/scss/forms/_check-radio-switch.scss +313 -215
  85. package/packages/fokus-components/scss/forms/_forms.scss +16 -0
  86. package/packages/fokus-core/scss/base/_accessibility.scss +14 -0
  87. package/packages/fokus-core/scss/tokens/_root.scss +11 -0
  88. package/packages/fokus-js/js/carousel.d.ts +4 -0
  89. package/packages/fokus-js/js/carousel.js +8 -0
  90. package/packages/fokus-js/js/core/positioning.js +18 -9
  91. package/packages/fokus-js/js/dropdown.d.ts +4 -0
  92. package/packages/fokus-js/js/dropdown.js +7 -0
  93. package/packages/fokus-js/js/popover.js +26 -1
  94. package/packages/fokus-js/js/tabs.d.ts +3 -0
  95. package/packages/fokus-js/js/tabs.js +5 -0
  96. package/packages/fokus-js/js/tag.js +17 -0
  97. package/packages/fokus-js/js/toast.js +77 -3
  98. package/packages/fokus-js/js/tooltip.d.ts +8 -1
  99. package/packages/fokus-js/js/tooltip.js +106 -13
  100. package/packages/fokus-utilities/scss/utilities/_api.scss +48 -0
  101. package/scss/entries/rtl-entry.scss +11 -0
@@ -67,6 +67,8 @@
67
67
  --fs-component-overlay-backdrop: rgb(0 0 0 / 55%);
68
68
  --fs-component-panel-radius: var(--fs-radius-md);
69
69
  --fs-component-panel-shadow: var(--fs-shadow-lg);
70
+ --fs-contrast-border-width: var(--fs-border-width);
71
+ --fs-contrast-focus-width: var(--fs-focus-width);
70
72
  --fs-cq-sm: 320px;
71
73
  --fs-cq-md: 480px;
72
74
  --fs-cq-lg: 640px;
@@ -145,6 +147,14 @@
145
147
  --fs-feedback-info-bg: oklch(96.4918490239% 0.0173174767 286.0707018324deg);
146
148
  }
147
149
  }
150
+ @media (prefers-contrast: more) {
151
+ :root {
152
+ --fs-contrast-border-width: 2px;
153
+ --fs-contrast-focus-width: 3px;
154
+ --fs-focus-width: var(--fs-contrast-focus-width);
155
+ --fs-border-width: var(--fs-contrast-border-width);
156
+ }
157
+ }
148
158
  }
149
159
  @layer tokens {
150
160
  :root {
@@ -267,6 +277,18 @@
267
277
  outline: 2px solid CanvasText;
268
278
  outline-offset: 2px;
269
279
  }
280
+ button,
281
+ [role=button],
282
+ input,
283
+ select,
284
+ textarea,
285
+ .fs-btn {
286
+ border-color: ButtonText;
287
+ forced-color-adjust: auto;
288
+ }
289
+ .fs-u-focus-ring:focus-visible {
290
+ outline: 3px solid Highlight;
291
+ }
270
292
  }
271
293
  }
272
294
  @layer utilities {
@@ -298,6 +320,20 @@
298
320
  }
299
321
  }
300
322
  @layer components {
323
+ .fs-form-fieldset {
324
+ min-inline-size: 0;
325
+ margin: 0;
326
+ padding: var(--fs-space-3);
327
+ border: var(--fs-border-width) solid var(--fs-color-border);
328
+ border-radius: var(--fs-radius-md);
329
+ }
330
+ .fs-form-fieldset > legend {
331
+ max-inline-size: 100%;
332
+ padding-inline: var(--fs-space-1);
333
+ color: var(--fs-color-text);
334
+ font-size: 0.75rem;
335
+ font-weight: 600;
336
+ }
301
337
  .fs-form-row {
302
338
  display: flex;
303
339
  flex-direction: row;
@@ -641,9 +677,53 @@
641
677
  .fs-switch {
642
678
  display: inline-flex;
643
679
  align-items: center;
680
+ min-inline-size: 0;
644
681
  }
645
682
  .fs-check {
646
- --fs-check-mark: var(--fs-color-on-primary);
683
+ --fs-check-size: 18px;
684
+ --fs-check-border-width: 2px;
685
+ --fs-check-radius: var(--fs-radius-sm);
686
+ --fs-check-gap: var(--fs-space-2);
687
+ --fs-check-mark-color: var(--fs-color-on-primary);
688
+ --fs-control-hover-bg: var(--fs-color-subtle);
689
+ --fs-control-active-bg: var(--fs-alert-primary-bg);
690
+ --fs-control-error-color: var(--fs-color-danger);
691
+ --fs-control-success-color: var(--fs-color-success);
692
+ }
693
+ .fs-radio {
694
+ --fs-radio-size: 18px;
695
+ --fs-radio-dot-size: 8px;
696
+ --fs-radio-radius: 50%;
697
+ --fs-radio-gap: var(--fs-space-2);
698
+ --fs-control-hover-bg: var(--fs-color-subtle);
699
+ --fs-control-active-bg: var(--fs-alert-primary-bg);
700
+ --fs-control-error-color: var(--fs-color-danger);
701
+ --fs-control-success-color: var(--fs-color-success);
702
+ }
703
+ .fs-switch {
704
+ --fs-switch-track-width: 40px;
705
+ --fs-switch-track-height: 24px;
706
+ --fs-switch-thumb-width: 18px;
707
+ --fs-switch-thumb-height: 18px;
708
+ --fs-switch-thumb-offset: 3px;
709
+ --fs-switch-on-offset: 19px;
710
+ --fs-switch-radius: var(--fs-radius-md);
711
+ --fs-switch-thumb-radius: var(--fs-radius-sm);
712
+ --fs-switch-gap: var(--fs-space-2);
713
+ --fs-switch-track-bg: var(--fs-color-subtle);
714
+ --fs-switch-track-border: var(--fs-color-border-default);
715
+ --fs-switch-track-checked-bg: var(--fs-color-primary);
716
+ --fs-switch-thumb-bg: var(--fs-color-surface);
717
+ --fs-switch-thumb-border: var(--fs-color-border-default);
718
+ --fs-switch-thumb-shadow: var(--fs-shadow-sm);
719
+ --fs-switch-track-shadow: inset 0 1px 1px rgb(15 23 42 / 12%);
720
+ --fs-switch-hover-ring: color-mix(in srgb, var(--fs-color-primary) 18%, transparent);
721
+ --fs-switch-hover-shadow: 0 0 0 4px var(--fs-switch-hover-ring);
722
+ --fs-switch-active-scale: 0.92;
723
+ --fs-control-hover-bg: var(--fs-color-subtle);
724
+ --fs-control-active-bg: var(--fs-alert-primary-bg);
725
+ --fs-control-error-color: var(--fs-color-danger);
726
+ --fs-control-success-color: var(--fs-color-success);
647
727
  }
648
728
  .fs-check-input,
649
729
  .fs-radio-input,
@@ -664,105 +744,140 @@
664
744
  position: relative;
665
745
  display: inline-flex;
666
746
  align-items: center;
667
- min-height: 20px;
668
- padding-left: 28px;
747
+ min-block-size: 24px;
748
+ min-inline-size: 24px;
669
749
  color: var(--fs-color-text);
670
750
  font-size: 0.8125rem;
751
+ line-height: 1.35;
671
752
  cursor: pointer;
672
753
  -webkit-user-select: none;
673
754
  user-select: none;
674
755
  }
756
+ .fs-check-label {
757
+ padding-inline-start: calc(var(--fs-check-size) + var(--fs-check-gap));
758
+ }
759
+ .fs-radio-label {
760
+ padding-inline-start: calc(var(--fs-radio-size) + var(--fs-radio-gap));
761
+ }
762
+ .fs-switch-label {
763
+ padding-inline-start: calc(var(--fs-switch-track-width) + var(--fs-switch-gap));
764
+ }
675
765
  .fs-check-label::before,
676
766
  .fs-radio-label::before,
677
767
  .fs-switch-label::before {
678
768
  position: absolute;
679
- left: 0;
769
+ inset-block-start: 50%;
680
770
  box-sizing: border-box;
681
- border: 1px solid var(--fs-color-border);
771
+ border: var(--fs-border-width) solid var(--fs-color-border);
682
772
  background-color: var(--fs-color-surface);
683
773
  content: "";
684
- transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
685
- }
686
- .fs-check-label::before,
687
- .fs-radio-label::before {
688
- width: 18px;
689
- height: 18px;
774
+ transform: translateY(-50%);
775
+ transition: background-color var(--fs-transition-fast) var(--fs-ease-standard), border-color var(--fs-transition-fast) var(--fs-ease-standard), box-shadow var(--fs-transition-fast) var(--fs-ease-standard);
690
776
  }
691
777
  .fs-check-label::before {
692
- border: 2px solid var(--fs-color-primary);
693
- border-radius: 0;
778
+ inset-inline-start: 0;
779
+ width: var(--fs-check-size);
780
+ height: var(--fs-check-size);
781
+ border-width: var(--fs-check-border-width);
782
+ border-radius: var(--fs-check-radius);
694
783
  }
695
784
  .fs-radio-label::before {
696
- border-radius: 50%;
785
+ inset-inline-start: 0;
786
+ width: var(--fs-radio-size);
787
+ height: var(--fs-radio-size);
788
+ border-radius: var(--fs-radio-radius);
697
789
  }
698
- .fs-check-label::after {
790
+ .fs-check-label::after,
791
+ .fs-radio-label::after,
792
+ .fs-switch-label::after {
699
793
  position: absolute;
700
- left: 4px;
701
- width: 9px;
702
- height: 5px;
703
794
  content: "";
704
795
  opacity: 0;
705
- border-bottom: 2px solid var(--fs-check-mark);
706
- border-left: 2px solid var(--fs-check-mark);
707
- transform: translateY(-1px) rotate(-45deg);
708
- transition: opacity 0.1s ease-in-out;
796
+ transition: opacity var(--fs-transition-fast) var(--fs-ease-standard), background-color var(--fs-transition-fast) var(--fs-ease-standard), inset-inline-start var(--fs-transition-fast) var(--fs-ease-standard), transform var(--fs-transition-fast) var(--fs-ease-standard);
797
+ }
798
+ .fs-check-label::after {
799
+ inset-inline-start: calc((var(--fs-check-size) - 9px) / 2);
800
+ inset-block-start: 50%;
801
+ width: 9px;
802
+ height: 5px;
803
+ border-block-end: 2px solid var(--fs-check-mark-color);
804
+ border-inline-start: 2px solid var(--fs-check-mark-color);
805
+ transform: translateY(-65%) rotate(-45deg);
709
806
  }
710
807
  .fs-radio-label::after {
711
- position: absolute;
712
- left: 5px;
713
- width: 8px;
714
- height: 8px;
808
+ inset-inline-start: calc((var(--fs-radio-size) - var(--fs-radio-dot-size)) / 2);
809
+ inset-block-start: 50%;
810
+ width: var(--fs-radio-dot-size);
811
+ height: var(--fs-radio-dot-size);
715
812
  border-radius: 50%;
716
- content: "";
717
- opacity: 0;
718
813
  background-color: var(--fs-color-on-primary);
719
- transition: opacity 0.1s ease-in-out;
814
+ transform: translateY(-50%);
720
815
  }
721
816
  .fs-check-input:checked + .fs-check-label::before,
722
817
  .fs-radio-input:checked + .fs-radio-label::before {
723
- background-color: var(--fs-color-primary);
724
818
  border-color: var(--fs-color-primary);
819
+ background-color: var(--fs-color-primary);
725
820
  }
726
821
  .fs-check-input:checked + .fs-check-label::after,
727
822
  .fs-radio-input:checked + .fs-radio-label::after {
728
823
  opacity: 1;
729
824
  }
730
- .fs-check-input:not(:checked, :indeterminate, :disabled, .is-invalid) + .fs-check-label:hover::before {
731
- background-color: color-mix(in srgb, var(--fs-color-primary) 10%, transparent);
825
+ .fs-check-input:not(:disabled, :indeterminate, .is-invalid) + .fs-check-label:hover::before,
826
+ .fs-radio-input:not(:disabled, .is-invalid) + .fs-radio-label:hover::before,
827
+ .fs-switch-input:not(:disabled, .is-invalid) + .fs-switch-label:hover::before {
828
+ background-color: var(--fs-control-hover-bg);
732
829
  }
733
- .fs-check-input:not(:disabled, :indeterminate, .is-invalid) + .fs-check-label:active::before {
734
- background-color: color-mix(in srgb, var(--fs-color-primary) 86%, var(--fs-color-black));
735
- border-color: var(--fs-color-primary);
736
- }
737
- .fs-check-input:checked:not(:disabled, .is-invalid) + .fs-check-label:active::after {
738
- transform: translateY(-1px) rotate(-45deg) scale(0.9);
830
+ .fs-check-input:checked:not(:disabled, .is-invalid) + .fs-check-label:hover::before,
831
+ .fs-radio-input:checked:not(:disabled, .is-invalid) + .fs-radio-label:hover::before,
832
+ .fs-switch-input:checked:not(:disabled, .is-invalid) + .fs-switch-label:hover::before {
833
+ background-color: color-mix(in srgb, var(--fs-color-primary) 88%, var(--fs-color-black));
739
834
  }
740
- .fs-switch-label {
741
- padding-left: 44px;
835
+ .fs-check-input:not(:disabled, .is-invalid) + .fs-check-label:active::before,
836
+ .fs-radio-input:not(:disabled, .is-invalid) + .fs-radio-label:active::before,
837
+ .fs-switch-input:not(:disabled, .is-invalid) + .fs-switch-label:active::before {
838
+ background-color: var(--fs-control-active-bg);
839
+ border-color: var(--fs-color-primary);
742
840
  }
743
841
  .fs-switch-label::before {
744
- width: 36px;
745
- height: 20px;
746
- border-radius: var(--fs-radius-md);
842
+ inset-inline-start: 0;
843
+ width: var(--fs-switch-track-width);
844
+ height: var(--fs-switch-track-height);
845
+ border-color: var(--fs-switch-track-border);
846
+ border-radius: var(--fs-switch-radius);
847
+ background-color: var(--fs-switch-track-bg);
848
+ box-shadow: var(--fs-switch-track-shadow);
747
849
  }
748
850
  .fs-switch-label::after {
749
- position: absolute;
750
- left: 2px;
751
- width: 16px;
752
- height: 14px;
753
- border-radius: var(--fs-radius-sm);
754
- content: "";
755
- background-color: var(--fs-color-border);
756
- transition: left 0.15s ease-in-out, background-color 0.15s ease-in-out;
851
+ inset-inline-start: var(--fs-switch-thumb-offset);
852
+ inset-block-start: 50%;
853
+ width: var(--fs-switch-thumb-width);
854
+ height: var(--fs-switch-thumb-height);
855
+ border-radius: var(--fs-switch-thumb-radius);
856
+ border: var(--fs-border-width) solid var(--fs-switch-thumb-border);
857
+ background-color: var(--fs-switch-thumb-bg);
858
+ opacity: 1;
859
+ transform: translateY(-50%);
860
+ box-shadow: var(--fs-switch-thumb-shadow);
757
861
  }
758
862
  .fs-switch-input:checked + .fs-switch-label::before {
759
- background-color: var(--fs-color-primary);
760
- border-color: var(--fs-color-primary);
863
+ border-color: var(--fs-switch-track-checked-bg);
864
+ background-color: var(--fs-switch-track-checked-bg);
865
+ box-shadow: none;
761
866
  }
762
867
  .fs-switch-input:checked + .fs-switch-label::after {
763
- left: 18px;
868
+ inset-inline-start: var(--fs-switch-on-offset);
869
+ border-color: var(--fs-color-on-primary);
764
870
  background-color: var(--fs-color-on-primary);
765
871
  }
872
+ .fs-switch-input:not(:disabled, .is-invalid) + .fs-switch-label:hover::before {
873
+ box-shadow: var(--fs-switch-hover-shadow), var(--fs-switch-track-shadow);
874
+ }
875
+ .fs-switch-input:checked:not(:disabled, .is-invalid) + .fs-switch-label:hover::before {
876
+ box-shadow: var(--fs-switch-hover-shadow);
877
+ }
878
+ .fs-switch-input:not(:disabled) + .fs-switch-label:active::after {
879
+ transform: translateY(-50%) scale(var(--fs-switch-active-scale));
880
+ }
766
881
  .fs-check-input:focus-visible + .fs-check-label::before,
767
882
  .fs-radio-input:focus-visible + .fs-radio-label::before,
768
883
  .fs-switch-input:focus-visible + .fs-switch-label::before {
@@ -771,153 +886,184 @@
771
886
  border-color: var(--fs-color-primary);
772
887
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--fs-color-primary) 22%, transparent);
773
888
  }
889
+ .fs-check-input:disabled + .fs-check-label,
774
890
  .fs-radio-input:disabled + .fs-radio-label,
775
891
  .fs-switch-input:disabled + .fs-switch-label {
776
- opacity: 0.5;
777
- pointer-events: none;
778
- }
779
- .fs-check-input:disabled + .fs-check-label {
780
892
  color: var(--fs-color-muted);
781
- opacity: 1;
893
+ cursor: default;
894
+ opacity: var(--fs-disabled-opacity);
782
895
  pointer-events: none;
783
896
  }
784
- .fs-check-input:disabled:not(:checked, :indeterminate) + .fs-check-label::before {
785
- border-color: var(--fs-color-border);
897
+ .fs-check-input:disabled + .fs-check-label::before,
898
+ .fs-radio-input:disabled + .fs-radio-label::before,
899
+ .fs-switch-input:disabled + .fs-switch-label::before {
900
+ border-color: var(--fs-switch-track-border);
901
+ background-color: var(--fs-switch-track-bg);
902
+ box-shadow: none;
903
+ }
904
+ .fs-switch-input:disabled + .fs-switch-label::after {
786
905
  background-color: var(--fs-color-subtle);
906
+ box-shadow: none;
787
907
  }
788
- .fs-check-input:disabled:checked + .fs-check-label::before {
789
- border-color: color-mix(in srgb, var(--fs-color-primary) 55%, var(--fs-color-border));
790
- background-color: color-mix(in srgb, var(--fs-color-primary) 45%, var(--fs-color-subtle));
908
+ .fs-check-input:disabled:checked + .fs-check-label::before,
909
+ .fs-radio-input:disabled:checked + .fs-radio-label::before,
910
+ .fs-switch-input:disabled:checked + .fs-switch-label::before {
911
+ border-color: color-mix(in srgb, var(--fs-switch-track-checked-bg) 55%, var(--fs-color-border));
912
+ background-color: color-mix(in srgb, var(--fs-switch-track-checked-bg) 45%, var(--fs-switch-track-bg));
791
913
  }
792
- .fs-check-input:disabled:checked + .fs-check-label::after {
793
- opacity: 0.72;
914
+ .fs-switch-input:disabled:checked + .fs-switch-label::after {
915
+ background-color: var(--fs-color-on-primary);
794
916
  }
795
- .fs-radio-input.is-valid + .fs-radio-label::before {
796
- border-color: var(--fs-color-success);
917
+ .fs-check-input.is-valid + .fs-check-label::before,
918
+ .fs-radio-input.is-valid + .fs-radio-label::before,
919
+ .fs-switch-input.is-valid + .fs-switch-label::before,
920
+ .fs-check-input[aria-invalid=false] + .fs-check-label::before,
921
+ .fs-radio-input[aria-invalid=false] + .fs-radio-label::before,
922
+ .fs-switch-input[aria-invalid=false] + .fs-switch-label::before {
923
+ border-color: var(--fs-control-success-color);
797
924
  }
798
925
  .fs-check-input.is-invalid + .fs-check-label::before,
799
- .fs-radio-input.is-invalid + .fs-radio-label::before {
800
- border-color: var(--fs-color-danger);
801
- }
802
- .fs-check-sm .fs-check-label,
803
- .fs-radio-sm .fs-radio-label {
804
- min-height: 16px;
805
- padding-left: 24px;
806
- font-size: 0.75rem;
926
+ .fs-radio-input.is-invalid + .fs-radio-label::before,
927
+ .fs-switch-input.is-invalid + .fs-switch-label::before,
928
+ .fs-check-input[aria-invalid=true] + .fs-check-label::before,
929
+ .fs-radio-input[aria-invalid=true] + .fs-radio-label::before,
930
+ .fs-switch-input[aria-invalid=true] + .fs-switch-label::before {
931
+ border-color: var(--fs-control-error-color);
932
+ }
933
+ .fs-switch-input.is-invalid:checked + .fs-switch-label::before,
934
+ .fs-switch-input[aria-invalid=true]:checked + .fs-switch-label::before {
935
+ background-color: var(--fs-control-error-color);
936
+ box-shadow: none;
937
+ }
938
+ .fs-switch-input.is-valid:checked + .fs-switch-label::before,
939
+ .fs-switch-input[aria-invalid=false]:checked + .fs-switch-label::before {
940
+ background-color: var(--fs-control-success-color);
941
+ border-color: var(--fs-control-success-color);
942
+ box-shadow: none;
807
943
  }
808
- .fs-check-sm .fs-check-label::before,
809
- .fs-radio-sm .fs-radio-label::before {
810
- width: 15px;
811
- height: 15px;
812
- }
813
- .fs-check-sm .fs-check-label::after {
814
- left: 3px;
815
- width: 8px;
816
- height: 4px;
817
- }
818
- .fs-radio-sm .fs-radio-label::after {
819
- left: 4px;
820
- width: 7px;
821
- height: 7px;
822
- }
823
- .fs-check-lg .fs-check-label,
824
- .fs-radio-lg .fs-radio-label {
825
- min-height: 24px;
826
- padding-left: 34px;
827
- font-size: 1rem;
944
+ .fs-check-input.is-invalid + .fs-check-label::before,
945
+ .fs-check-input[aria-invalid=true] + .fs-check-label::before {
946
+ background-color: var(--fs-control-error-color);
828
947
  }
829
- .fs-check-lg .fs-check-label::before,
830
- .fs-radio-lg .fs-radio-label::before {
831
- width: 22px;
832
- height: 22px;
948
+ .fs-check-input.is-invalid + .fs-check-label::after,
949
+ .fs-check-input[aria-invalid=true] + .fs-check-label::after {
950
+ inset-inline-start: 50%;
951
+ inset-block-start: 50%;
952
+ width: 9px;
953
+ height: 9px;
954
+ border: 0;
955
+ background-image: linear-gradient(45deg, transparent 42%, var(--fs-color-on-danger, var(--fs-color-white)) 42% 58%, transparent 58%), linear-gradient(-45deg, transparent 42%, var(--fs-color-on-danger, var(--fs-color-white)) 42% 58%, transparent 58%);
956
+ opacity: 1;
957
+ transform: translate(-50%, -50%);
833
958
  }
834
- .fs-check-lg .fs-check-label::after {
835
- left: 5px;
836
- width: 11px;
837
- height: 6px;
959
+ .fs-check-input:indeterminate + .fs-check-label::before {
960
+ border-color: var(--fs-color-primary);
961
+ background-color: var(--fs-color-surface);
838
962
  }
839
- .fs-radio-lg .fs-radio-label::after {
840
- left: 6px;
963
+ .fs-check-input:indeterminate + .fs-check-label::after {
964
+ inset-inline-start: calc((var(--fs-check-size) - 10px) / 2);
965
+ inset-block-start: 50%;
841
966
  width: 10px;
842
- height: 10px;
967
+ height: 2px;
968
+ border: 0;
969
+ border-radius: 1px;
970
+ background-color: var(--fs-color-primary);
971
+ opacity: 1;
972
+ transform: translateY(-50%);
843
973
  }
844
- .fs-switch-sm .fs-switch-label {
845
- min-height: 16px;
846
- padding-left: 38px;
974
+ .fs-check-sm,
975
+ .fs-radio-sm,
976
+ .fs-switch-sm {
847
977
  font-size: 0.75rem;
848
978
  }
849
- .fs-switch-sm .fs-switch-label::before {
850
- width: 30px;
851
- height: 16px;
852
- }
853
- .fs-switch-sm .fs-switch-label::after {
854
- width: 12px;
855
- height: 10px;
856
- }
857
- .fs-switch-sm .fs-switch-input:checked + .fs-switch-label::after {
858
- left: 16px;
859
- }
860
- .fs-switch-lg .fs-switch-label {
861
- min-height: 26px;
862
- padding-left: 52px;
979
+ .fs-check-sm {
980
+ --fs-check-size: 15px;
981
+ --fs-check-gap: 9px;
982
+ }
983
+ .fs-radio-sm {
984
+ --fs-radio-size: 15px;
985
+ --fs-radio-dot-size: 7px;
986
+ --fs-radio-gap: 9px;
987
+ }
988
+ .fs-switch-sm {
989
+ --fs-switch-track-width: 32px;
990
+ --fs-switch-track-height: 18px;
991
+ --fs-switch-thumb-width: 14px;
992
+ --fs-switch-thumb-height: 14px;
993
+ --fs-switch-thumb-offset: 2px;
994
+ --fs-switch-on-offset: 16px;
995
+ --fs-switch-hover-shadow: 0 0 0 3px var(--fs-switch-hover-ring);
996
+ }
997
+ .fs-check-lg,
998
+ .fs-radio-lg,
999
+ .fs-switch-lg {
863
1000
  font-size: 1rem;
864
1001
  }
865
- .fs-switch-lg .fs-switch-label::before {
866
- width: 44px;
867
- height: 24px;
1002
+ .fs-check-lg {
1003
+ --fs-check-size: 22px;
1004
+ --fs-check-gap: 12px;
868
1005
  }
869
- .fs-switch-lg .fs-switch-label::after {
870
- width: 20px;
871
- height: 18px;
1006
+ .fs-radio-lg {
1007
+ --fs-radio-size: 22px;
1008
+ --fs-radio-dot-size: 10px;
1009
+ --fs-radio-gap: 12px;
872
1010
  }
873
- .fs-switch-lg .fs-switch-input:checked + .fs-switch-label::after {
874
- left: 22px;
1011
+ .fs-switch-lg {
1012
+ --fs-switch-track-width: 48px;
1013
+ --fs-switch-track-height: 28px;
1014
+ --fs-switch-thumb-width: 22px;
1015
+ --fs-switch-thumb-height: 22px;
1016
+ --fs-switch-thumb-offset: 3px;
1017
+ --fs-switch-on-offset: 23px;
1018
+ --fs-switch-hover-shadow: 0 0 0 5px var(--fs-switch-hover-ring);
875
1019
  }
876
- .fs-check-input:indeterminate + .fs-check-label::before {
877
- border: 2px dashed var(--fs-color-primary);
878
- background-color: var(--fs-color-surface);
1020
+ @media (prefers-reduced-motion: reduce) {
1021
+ .fs-check-label::before,
1022
+ .fs-check-label::after,
1023
+ .fs-radio-label::before,
1024
+ .fs-radio-label::after,
1025
+ .fs-switch-label::before,
1026
+ .fs-switch-label::after {
1027
+ transition-duration: 0ms;
1028
+ }
879
1029
  }
880
- .fs-check-input:indeterminate + .fs-check-label::after {
881
- left: 4px;
882
- width: 10px;
883
- height: 0;
884
- opacity: 1;
885
- border-bottom: 2px solid var(--fs-color-primary);
886
- border-left: 0;
887
- transform: translateY(3px) rotate(0deg);
888
- }
889
- .fs-check-sm .fs-check-input:indeterminate + .fs-check-label::after {
890
- left: 3px;
891
- width: 8px;
892
- }
893
- .fs-check-lg .fs-check-input:indeterminate + .fs-check-label::after {
894
- left: 5px;
895
- width: 12px;
896
- }
897
- .fs-check-input.is-invalid + .fs-check-label::before {
898
- background-color: var(--fs-color-danger);
899
- }
900
- .fs-check-input.is-invalid + .fs-check-label::after {
901
- top: 6px;
902
- left: 5px;
903
- width: 8px;
904
- height: 8px;
905
- opacity: 1;
906
- border: 0;
907
- background-image: linear-gradient(45deg, transparent 42%, #ffffff 42% 58%, transparent 58%), linear-gradient(-45deg, transparent 42%, #ffffff 42% 58%, transparent 58%);
908
- transform: none;
909
- }
910
- .fs-check-sm .fs-check-input.is-invalid + .fs-check-label::after {
911
- top: 5px;
912
- left: 4px;
913
- width: 7px;
914
- height: 7px;
915
- }
916
- .fs-check-lg .fs-check-input.is-invalid + .fs-check-label::after {
917
- top: 6px;
918
- left: 6px;
919
- width: 10px;
920
- height: 10px;
1030
+ @media (prefers-contrast: more) {
1031
+ .fs-check,
1032
+ .fs-radio,
1033
+ .fs-switch {
1034
+ --fs-border-width: 2px;
1035
+ --fs-focus-width: 3px;
1036
+ }
1037
+ }
1038
+ @media (forced-colors: active) {
1039
+ .fs-check-label::before,
1040
+ .fs-radio-label::before,
1041
+ .fs-switch-label::before,
1042
+ .fs-switch-label::after {
1043
+ border-color: ButtonText;
1044
+ forced-color-adjust: auto;
1045
+ }
1046
+ .fs-check-input:checked + .fs-check-label::before,
1047
+ .fs-radio-input:checked + .fs-radio-label::before,
1048
+ .fs-switch-input:checked + .fs-switch-label::before {
1049
+ background-color: Highlight;
1050
+ border-color: Highlight;
1051
+ }
1052
+ .fs-switch-label::after {
1053
+ background-color: ButtonFace;
1054
+ border-color: ButtonText;
1055
+ box-shadow: none;
1056
+ }
1057
+ .fs-switch-input:checked + .fs-switch-label::after {
1058
+ background-color: HighlightText;
1059
+ border-color: HighlightText;
1060
+ }
1061
+ .fs-check-input:focus-visible + .fs-check-label::before,
1062
+ .fs-radio-input:focus-visible + .fs-radio-label::before,
1063
+ .fs-switch-input:focus-visible + .fs-switch-label::before {
1064
+ outline: 3px solid Highlight;
1065
+ outline-offset: 2px;
1066
+ }
921
1067
  }
922
1068
  }
923
1069
  @layer components {