fokus-styles 2.0.0 → 2.3.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 (131) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +4 -3
  3. package/dist/css/components.css +510 -2
  4. package/dist/css/components.css.map +1 -1
  5. package/dist/css/components.min.css +1 -1
  6. package/dist/css/components.min.css.map +1 -1
  7. package/dist/css/fokus-components.css +4050 -0
  8. package/dist/css/fokus-components.css.map +1 -0
  9. package/dist/css/fokus-components.min.css +2 -0
  10. package/dist/css/fokus-components.min.css.map +1 -0
  11. package/dist/css/fokus-core.css +1563 -0
  12. package/dist/css/fokus-core.css.map +1 -0
  13. package/dist/css/fokus-core.min.css +2 -0
  14. package/dist/css/fokus-core.min.css.map +1 -0
  15. package/dist/css/fokus-dark.css +304 -0
  16. package/dist/css/fokus-dark.css.map +1 -0
  17. package/dist/css/fokus-dark.min.css +2 -0
  18. package/dist/css/fokus-dark.min.css.map +1 -0
  19. package/dist/css/fokus-utilities.css +4176 -0
  20. package/dist/css/fokus-utilities.css.map +1 -0
  21. package/dist/css/fokus-utilities.min.css +2 -0
  22. package/dist/css/fokus-utilities.min.css.map +1 -0
  23. package/dist/css/fokus.css +1339 -53
  24. package/dist/css/fokus.css.map +1 -1
  25. package/dist/css/fokus.min.css +1 -1
  26. package/dist/css/fokus.min.css.map +1 -1
  27. package/dist/css/forms.css +115 -2
  28. package/dist/css/forms.css.map +1 -1
  29. package/dist/css/forms.min.css +1 -1
  30. package/dist/css/forms.min.css.map +1 -1
  31. package/dist/css/helpers.css +376 -2
  32. package/dist/css/helpers.css.map +1 -1
  33. package/dist/css/helpers.min.css +1 -1
  34. package/dist/css/helpers.min.css.map +1 -1
  35. package/dist/css/layout.css +560 -2
  36. package/dist/css/layout.css.map +1 -1
  37. package/dist/css/layout.min.css +1 -1
  38. package/dist/css/layout.min.css.map +1 -1
  39. package/dist/js/fokus.js +347 -12
  40. package/dist/js/fokus.js.map +4 -4
  41. package/dist/js/fokus.min.js +17 -17
  42. package/dist/js/fokus.min.js.map +4 -4
  43. package/docs/components/accordion.md +3 -0
  44. package/docs/components/avatar.md +13 -0
  45. package/docs/components/button-group.md +13 -0
  46. package/docs/components/close-button.md +13 -0
  47. package/docs/components/code.md +13 -0
  48. package/docs/components/icon-link.md +13 -0
  49. package/docs/components/list-group.md +13 -0
  50. package/docs/components/modal.md +3 -0
  51. package/docs/components/navbar.md +3 -0
  52. package/docs/components/pagination.md +3 -0
  53. package/docs/components/placeholder.md +13 -0
  54. package/docs/components/ratio.md +13 -0
  55. package/docs/components/scrollspy.md +13 -0
  56. package/docs/components/skeleton.md +3 -0
  57. package/docs/components/table.md +3 -0
  58. package/docs/guides/javascript-api.md +9 -0
  59. package/docs/guides/utility-api.md +9 -0
  60. package/docs/reference/size-baseline.json +13 -13
  61. package/mockup/assets/example-theme.css +3 -1
  62. package/mockup/assets/example-theme.js +2 -0
  63. package/mockup/assets/showcase-contracts.js +2 -2
  64. package/mockup/assets/showcase.css +4 -2
  65. package/mockup/assets/showcase.js +2 -0
  66. package/mockup/examples/js-foundation.html +25 -0
  67. package/mockup/examples/tables-navbar.html +12 -8
  68. package/mockup/examples/theming.html +2 -1
  69. package/mockup/foundations.html +2 -2
  70. package/package.json +14 -1
  71. package/packages/fokus-cli/bin/fokus.mjs +18 -1
  72. package/packages/fokus-cli/lib/build.mjs +12 -2
  73. package/packages/fokus-components/scss/components/_accordion.scss +19 -0
  74. package/packages/fokus-components/scss/components/_avatar.scss +22 -0
  75. package/packages/fokus-components/scss/components/_button-group.scss +14 -0
  76. package/packages/fokus-components/scss/components/_close-button.scss +22 -0
  77. package/packages/fokus-components/scss/components/_code.scss +19 -0
  78. package/packages/fokus-components/scss/components/_icon-link.scss +8 -0
  79. package/packages/fokus-components/scss/components/_index.scss +10 -0
  80. package/packages/fokus-components/scss/components/_list-group.scss +26 -0
  81. package/packages/fokus-components/scss/components/_modal.scss +36 -0
  82. package/packages/fokus-components/scss/components/_navbar.scss +48 -0
  83. package/packages/fokus-components/scss/components/_offcanvas.scss +19 -0
  84. package/packages/fokus-components/scss/components/_pagination.scss +10 -0
  85. package/packages/fokus-components/scss/components/_placeholder.scss +13 -0
  86. package/packages/fokus-components/scss/components/_progress.scss +8 -0
  87. package/packages/fokus-components/scss/components/_ratio.scss +10 -0
  88. package/packages/fokus-components/scss/components/_scrollspy.scss +5 -0
  89. package/packages/fokus-components/scss/components/_skeleton.scss +19 -0
  90. package/packages/fokus-components/scss/components/_spinner.scss +9 -53
  91. package/packages/fokus-components/scss/components/_tables.scss +20 -0
  92. package/packages/fokus-components/scss/forms/_forms.scss +29 -0
  93. package/packages/fokus-core/scss/base/_accessibility.scss +45 -0
  94. package/packages/fokus-core/scss/base/_index.scss +1 -0
  95. package/packages/fokus-core/scss/layout/_grid.scss +18 -0
  96. package/packages/fokus-core/scss/settings/_config.scss +43 -0
  97. package/packages/fokus-core/scss/settings/_index.scss +1 -0
  98. package/packages/fokus-core/scss/themes/_dark.scss +38 -2
  99. package/packages/fokus-core/scss/tokens/_root.scss +14 -0
  100. package/packages/fokus-core/scss/tools/_mixins.scss +8 -0
  101. package/packages/fokus-js/js/accordion.js +7 -1
  102. package/packages/fokus-js/js/core/focus.js +20 -0
  103. package/packages/fokus-js/js/core/overlay.d.ts +2 -0
  104. package/packages/fokus-js/js/core/overlay.js +10 -0
  105. package/packages/fokus-js/js/core/register.js +4 -2
  106. package/packages/fokus-js/js/focus-trap.d.ts +3 -0
  107. package/packages/fokus-js/js/focus-trap.js +1 -0
  108. package/packages/fokus-js/js/fokus.d.ts +7 -0
  109. package/packages/fokus-js/js/fokus.js +7 -0
  110. package/packages/fokus-js/js/form-validation.d.ts +7 -0
  111. package/packages/fokus-js/js/form-validation.js +20 -0
  112. package/packages/fokus-js/js/modal.js +16 -2
  113. package/packages/fokus-js/js/navbar.d.ts +10 -0
  114. package/packages/fokus-js/js/navbar.js +27 -0
  115. package/packages/fokus-js/js/offcanvas.d.ts +4 -0
  116. package/packages/fokus-js/js/offcanvas.js +16 -2
  117. package/packages/fokus-js/js/pagination.d.ts +7 -0
  118. package/packages/fokus-js/js/pagination.js +38 -0
  119. package/packages/fokus-js/js/scrollspy.d.ts +7 -0
  120. package/packages/fokus-js/js/scrollspy.js +26 -0
  121. package/packages/fokus-js/js/spinner.d.ts +9 -0
  122. package/packages/fokus-js/js/spinner.js +18 -0
  123. package/packages/fokus-js/js/theme.d.ts +9 -0
  124. package/packages/fokus-js/js/theme.js +19 -0
  125. package/packages/fokus-js/js/toast.js +4 -0
  126. package/packages/fokus-utilities/scss/utilities/_api.scss +48 -0
  127. package/packages/fokus-utilities/scss/utilities/_index.scss +2 -0
  128. package/packages/fokus-utilities/scss/utilities/_states.scss +19 -0
  129. package/packages/fokus-utilities/scss/utilities/_visibility.scss +24 -0
  130. package/scss/entries/core-entry.scss +5 -0
  131. package/scss/entries/dark-entry.scss +3 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.3.0] - 2026-09-07
4
+
5
+ - adiciona registro compartilhado de overlays, evitando múltiplos Modal/Offcanvas concorrentes;
6
+ - amplia o contrato TypeScript do núcleo de overlay;
7
+ - mantém o gerenciamento de foco, `inert`, scroll lock e eventos `fs:*` coordenados entre componentes.
8
+
9
+ ## [2.2.0] - 2026-09-07
10
+
11
+ - adiciona Utility API Sass configurável para cores, espaçamento, sizing e variantes responsivas;
12
+ - adiciona tokens de configuração para presets e inclusão seletiva de famílias de utilitários;
13
+ - adiciona `Spinner`, `Pagination` dinâmica e fallback de Scrollspy sem `IntersectionObserver`;
14
+ - adiciona suporte a `inert`/`aria-hidden` no focus trap e estilos do spinner com redução de movimento.
15
+
3
16
  ## Unreleased
4
17
 
5
18
  - refina o Carousel com tokens locais, controles compactos, indicadores em
package/README.md CHANGED
@@ -24,7 +24,7 @@ profissionais, e é distribuído publicamente como produto para qualquer
24
24
  desenvolvedor que precise construir interfaces consistentes sem carregar
25
25
  React, Vue, Angular, jQuery ou qualquer outra dependência de runtime.
26
26
 
27
- > **Status:** `2.0.0`. O Fokus Styles consolida CSS, JavaScript, ícones, React
27
+ > **Status:** `2.1.0`. O Fokus Styles consolida CSS, JavaScript, ícones, React
28
28
  > e CLI em um único pacote npm. O foco atual é consolidar o núcleo CSS e os componentes
29
29
  > essenciais antes de ampliar o catálogo. O framework já possui componentes
30
30
  > avançados, mas eles são tratados como extensões e não definem o caminho
@@ -67,8 +67,9 @@ Ou direto via CDN (jsDelivr/unpkg), sem instalar nada:
67
67
  <script src="https://cdn.jsdelivr.net/npm/fokus-styles/dist/js/fokus.js"></script>
68
68
  ```
69
69
 
70
- O CSS também é distribuído em arquivos separados (`layout.css`, `forms.css`,
71
- `components.css`, `helpers.css`), e o ponto de entrada Sass está disponível para
70
+ O CSS também é distribuído em arquivos separados (`fokus-core.css`,
71
+ `fokus-components.css`, `fokus-utilities.css`, `fokus-dark.css`, além de
72
+ `layout.css`, `forms.css`, `components.css`, `helpers.css`), e o ponto de entrada Sass está disponível para
72
73
  compilar com suas próprias variáveis. Detalhes em
73
74
  [Instalação](docs/getting-started/installation.md) e
74
75
  [Formas de uso](docs/getting-started/usage.md).
@@ -48,12 +48,26 @@
48
48
  --fs-control-padding-x-lg: 16px;
49
49
  --fs-focus-width: 2px;
50
50
  --fs-focus-offset: 2px;
51
+ --fs-focus-color: var(--fs-color-primary);
52
+ --fs-focus-ring-size: 3px;
53
+ --fs-focus-ring-color: color-mix(in srgb, var(--fs-focus-color) 22%, transparent);
51
54
  --fs-focus-ring-alpha: 22%;
52
55
  --fs-transition-fast: 150ms;
53
56
  --fs-transition-normal: 220ms;
57
+ --fs-motion-duration-fast: var(--fs-transition-fast);
58
+ --fs-motion-duration-normal: var(--fs-transition-normal);
59
+ --fs-motion-ease-standard: var(--fs-ease-standard);
54
60
  --fs-ease-standard: cubic-bezier(0.2, 0, 0, 1);
55
61
  --fs-border-width: 1px;
56
62
  --fs-disabled-opacity: 0.5;
63
+ --fs-safe-area-top: env(safe-area-inset-top, 0px);
64
+ --fs-safe-area-right: env(safe-area-inset-right, 0px);
65
+ --fs-safe-area-bottom: env(safe-area-inset-bottom, 0px);
66
+ --fs-safe-area-left: env(safe-area-inset-left, 0px);
67
+ --fs-component-control-height: var(--fs-control-height);
68
+ --fs-component-overlay-backdrop: rgb(0 0 0 / 55%);
69
+ --fs-component-panel-radius: var(--fs-radius-md);
70
+ --fs-component-panel-shadow: var(--fs-shadow-lg);
57
71
  --fs-cq-sm: 320px;
58
72
  --fs-cq-md: 480px;
59
73
  --fs-cq-lg: 640px;
@@ -243,6 +257,47 @@
243
257
  }
244
258
  }
245
259
  }
260
+ /* stylelint-disable property-no-deprecated, selector-not-notation */
261
+ @layer reset {
262
+ :focus-visible {
263
+ outline: var(--fs-focus-width) solid var(--fs-focus-color);
264
+ outline-offset: var(--fs-focus-offset);
265
+ }
266
+ @media (forced-colors: active) {
267
+ :focus-visible {
268
+ outline: 2px solid CanvasText;
269
+ outline-offset: 2px;
270
+ }
271
+ }
272
+ }
273
+ @layer utilities {
274
+ .fs-u-visually-hidden:not(:focus):not(:focus-within),
275
+ .fs-u-visually-hidden-focusable:not(:focus):not(:focus-within) {
276
+ position: absolute !important;
277
+ width: 1px !important;
278
+ height: 1px !important;
279
+ padding: 0 !important;
280
+ margin: -1px !important;
281
+ overflow: hidden !important;
282
+ clip-path: inset(50%) !important;
283
+ white-space: nowrap !important;
284
+ border: 0 !important;
285
+ }
286
+ .fs-skip-link {
287
+ position: fixed;
288
+ z-index: 1000;
289
+ inset-block-start: var(--fs-space-2);
290
+ inset-inline-start: var(--fs-space-2);
291
+ transform: translateY(-200%);
292
+ padding: var(--fs-space-2) var(--fs-space-3);
293
+ color: var(--fs-color-on-primary);
294
+ background: var(--fs-color-primary);
295
+ border-radius: var(--fs-radius-sm);
296
+ }
297
+ .fs-skip-link:focus {
298
+ transform: translateY(0);
299
+ }
300
+ }
246
301
  @layer components {
247
302
  .fs-btn {
248
303
  --fs-btn-color: var(--fs-color-text-primary);
@@ -847,6 +902,23 @@
847
902
  .fs-table-responsive {
848
903
  overflow-x: auto;
849
904
  }
905
+ .fs-table-caption {
906
+ caption-side: top;
907
+ padding: var(--fs-space-2) 0;
908
+ color: var(--fs-color-muted);
909
+ text-align: start;
910
+ }
911
+ .fs-table-empty {
912
+ padding: var(--fs-space-5);
913
+ color: var(--fs-color-muted);
914
+ text-align: center;
915
+ }
916
+ @media (width < 640px) {
917
+ .fs-table-priority th:nth-child(n+4),
918
+ .fs-table-priority td:nth-child(n+4) {
919
+ display: none;
920
+ }
921
+ }
850
922
  }
851
923
  @layer components {
852
924
  .fs-navbar {
@@ -873,6 +945,47 @@
873
945
  padding: 0;
874
946
  list-style: none;
875
947
  }
948
+ .fs-navbar-toggler {
949
+ display: inline-flex;
950
+ align-items: center;
951
+ justify-content: center;
952
+ min-width: 44px;
953
+ min-height: 44px;
954
+ padding: 8px;
955
+ color: var(--fs-color-text);
956
+ background: transparent;
957
+ border: 1px solid var(--fs-color-border);
958
+ border-radius: var(--fs-radius-sm);
959
+ cursor: pointer;
960
+ }
961
+ .fs-navbar-collapse {
962
+ flex-basis: 100%;
963
+ width: 100%;
964
+ }
965
+ .fs-navbar-collapse:not(.is-open) {
966
+ display: none;
967
+ }
968
+ .fs-navbar-collapse.is-open .fs-navbar-nav {
969
+ flex-direction: column;
970
+ align-items: stretch;
971
+ }
972
+ @media (width >= 768px) {
973
+ .fs-navbar-toggler {
974
+ display: none;
975
+ }
976
+ .fs-navbar-collapse,
977
+ .fs-navbar-collapse:not(.is-open),
978
+ .fs-navbar-collapse[hidden] {
979
+ display: flex;
980
+ flex: 1 1 auto;
981
+ align-items: center;
982
+ justify-content: flex-end;
983
+ width: auto;
984
+ }
985
+ .fs-navbar-collapse .fs-navbar-nav {
986
+ flex-direction: row;
987
+ }
988
+ }
876
989
  .fs-nav-link {
877
990
  display: inline-flex;
878
991
  align-items: center;
@@ -1286,6 +1399,13 @@
1286
1399
  .fs-modal-dialog.fs-modal-lg {
1287
1400
  max-width: 720px;
1288
1401
  }
1402
+ .fs-modal-dialog.fs-modal-xl {
1403
+ max-width: 1140px;
1404
+ }
1405
+ .fs-modal-dialog.fs-modal-fullscreen {
1406
+ max-width: none;
1407
+ height: 100%;
1408
+ }
1289
1409
  .fs-modal-content {
1290
1410
  display: flex;
1291
1411
  flex-direction: column;
@@ -1312,6 +1432,28 @@
1312
1432
  padding: 20px;
1313
1433
  overflow-y: auto;
1314
1434
  }
1435
+ .fs-modal-scrollable .fs-modal-content {
1436
+ overflow: hidden;
1437
+ }
1438
+ .fs-modal-scrollable .fs-modal-body {
1439
+ overflow-y: auto;
1440
+ }
1441
+ @media (width < 640px) {
1442
+ .fs-modal {
1443
+ align-items: flex-end;
1444
+ padding: 0;
1445
+ }
1446
+ .fs-modal-dialog,
1447
+ .fs-modal-dialog.fs-modal-sm,
1448
+ .fs-modal-dialog.fs-modal-lg,
1449
+ .fs-modal-dialog.fs-modal-xl {
1450
+ max-width: none;
1451
+ }
1452
+ .fs-modal-content {
1453
+ max-height: calc(100dvh - var(--fs-safe-area-top));
1454
+ border-radius: var(--fs-radius-md) var(--fs-radius-md) 0 0;
1455
+ }
1456
+ }
1315
1457
  .fs-modal-footer {
1316
1458
  display: flex;
1317
1459
  align-items: center;
@@ -1675,6 +1817,22 @@
1675
1817
  padding: 16px 20px;
1676
1818
  border-top: 1px solid var(--fs-color-border);
1677
1819
  }
1820
+ .fs-offcanvas-responsive {
1821
+ width: min(100%, 420px);
1822
+ }
1823
+ @media (width >= 1024px) {
1824
+ .fs-offcanvas-lg {
1825
+ position: static;
1826
+ width: auto;
1827
+ height: auto;
1828
+ visibility: visible;
1829
+ transform: none;
1830
+ box-shadow: none;
1831
+ }
1832
+ .fs-offcanvas-lg + .fs-offcanvas-backdrop {
1833
+ display: none;
1834
+ }
1835
+ }
1678
1836
  @media (prefers-reduced-motion: reduce) {
1679
1837
  .fs-offcanvas,
1680
1838
  .fs-offcanvas-backdrop {
@@ -1703,6 +1861,16 @@
1703
1861
  border-bottom-right-radius: var(--fs-radius-md);
1704
1862
  border-bottom-left-radius: var(--fs-radius-md);
1705
1863
  }
1864
+ .fs-accordion-flush .fs-accordion-item {
1865
+ border-inline: 0;
1866
+ border-radius: 0;
1867
+ }
1868
+ .fs-accordion-flush .fs-accordion-item:first-child {
1869
+ border-block-start: 0;
1870
+ }
1871
+ .fs-accordion-always-open .fs-accordion-button[aria-expanded=true]::after {
1872
+ transform: rotate(-135deg);
1873
+ }
1706
1874
  .fs-accordion-header {
1707
1875
  margin: 0;
1708
1876
  }
@@ -1751,6 +1919,11 @@
1751
1919
  border-top: 1px solid var(--fs-color-border);
1752
1920
  background-color: var(--fs-color-surface-raised);
1753
1921
  }
1922
+ @media (prefers-reduced-motion: reduce) {
1923
+ .fs-accordion-button::after {
1924
+ transition: none;
1925
+ }
1926
+ }
1754
1927
  }
1755
1928
  @layer components {
1756
1929
  .fs-tabs {
@@ -2012,6 +2185,14 @@
2012
2185
  padding: 0;
2013
2186
  list-style: none;
2014
2187
  }
2188
+ .fs-pagination-scroll {
2189
+ max-width: 100%;
2190
+ overflow-x: auto;
2191
+ padding-block: 2px;
2192
+ }
2193
+ .fs-pagination-scroll .fs-pagination {
2194
+ width: max-content;
2195
+ }
2015
2196
  .fs-page-link {
2016
2197
  display: inline-flex;
2017
2198
  align-items: center;
@@ -2240,6 +2421,9 @@
2240
2421
  --fs-progress-bar-bg: var(--fs-color-info);
2241
2422
  --fs-progress-color: #ffffff;
2242
2423
  }
2424
+ .fs-spinner[data-fs-loading=false] {
2425
+ display: none;
2426
+ }
2243
2427
  .fs-progress-sm {
2244
2428
  --fs-progress-height: 4px;
2245
2429
  }
@@ -2965,6 +3149,22 @@
2965
3149
  .fs-skeleton-rect {
2966
3150
  border-radius: var(--fs-radius-md);
2967
3151
  }
3152
+ .fs-skeleton-card {
3153
+ display: grid;
3154
+ gap: var(--fs-space-3);
3155
+ min-height: 10rem;
3156
+ padding: var(--fs-space-4);
3157
+ border-radius: var(--fs-radius-md);
3158
+ }
3159
+ .fs-skeleton-table {
3160
+ height: 1.25rem;
3161
+ margin-block-end: var(--fs-space-2);
3162
+ }
3163
+ .fs-skeleton-avatar {
3164
+ width: 2.5rem;
3165
+ height: 2.5rem;
3166
+ border-radius: 50%;
3167
+ }
2968
3168
  @keyframes fokus-skeleton-pulse {
2969
3169
  0%, 100% {
2970
3170
  opacity: 1;
@@ -3352,6 +3552,280 @@
3352
3552
  font-size: 1rem;
3353
3553
  }
3354
3554
  }
3555
+ /* stylelint-disable declaration-block-single-line-max-declarations */
3556
+ @layer components {
3557
+ .fs-avatar {
3558
+ display: inline-flex;
3559
+ flex: 0 0 auto;
3560
+ align-items: center;
3561
+ justify-content: center;
3562
+ width: 2.5rem;
3563
+ height: 2.5rem;
3564
+ overflow: hidden;
3565
+ color: var(--fs-color-on-primary);
3566
+ font-weight: 600;
3567
+ background: var(--fs-color-primary);
3568
+ border-radius: 50%;
3569
+ object-fit: cover;
3570
+ }
3571
+ .fs-avatar-sm {
3572
+ width: 2rem;
3573
+ height: 2rem;
3574
+ font-size: 0.8125rem;
3575
+ }
3576
+ .fs-avatar-lg {
3577
+ width: 3.5rem;
3578
+ height: 3.5rem;
3579
+ font-size: 1.25rem;
3580
+ }
3581
+ .fs-avatar-square {
3582
+ border-radius: var(--fs-radius-md);
3583
+ }
3584
+ .fs-avatar img {
3585
+ width: 100%;
3586
+ height: 100%;
3587
+ object-fit: cover;
3588
+ }
3589
+ }
3590
+ /* stylelint-disable declaration-block-single-line-max-declarations */
3591
+ @layer components {
3592
+ .fs-button-group {
3593
+ display: inline-flex;
3594
+ vertical-align: middle;
3595
+ }
3596
+ .fs-button-group > .fs-btn {
3597
+ border-radius: 0;
3598
+ }
3599
+ .fs-button-group > .fs-btn:first-child {
3600
+ border-start-start-radius: var(--fs-radius-sm);
3601
+ border-end-start-radius: var(--fs-radius-sm);
3602
+ }
3603
+ .fs-button-group > .fs-btn:last-child {
3604
+ border-start-end-radius: var(--fs-radius-sm);
3605
+ border-end-end-radius: var(--fs-radius-sm);
3606
+ }
3607
+ .fs-button-group > .fs-btn + .fs-btn {
3608
+ margin-inline-start: -1px;
3609
+ }
3610
+ .fs-button-group-vertical {
3611
+ flex-direction: column;
3612
+ align-items: flex-start;
3613
+ }
3614
+ .fs-button-group-vertical > .fs-btn {
3615
+ width: 100%;
3616
+ }
3617
+ }
3618
+ /* stylelint-disable declaration-block-single-line-max-declarations */
3619
+ @layer components {
3620
+ .fs-close {
3621
+ display: inline-grid;
3622
+ width: 2rem;
3623
+ height: 2rem;
3624
+ place-items: center;
3625
+ padding: 0;
3626
+ color: currentcolor;
3627
+ font-size: 1.5rem;
3628
+ line-height: 1;
3629
+ background: transparent;
3630
+ border: 0;
3631
+ border-radius: 50%;
3632
+ cursor: pointer;
3633
+ opacity: 0.72;
3634
+ }
3635
+ .fs-close::before {
3636
+ content: "×";
3637
+ }
3638
+ .fs-close:hover {
3639
+ opacity: 1;
3640
+ background: var(--fs-color-subtle);
3641
+ }
3642
+ .fs-close:focus-visible {
3643
+ outline: var(--fs-focus-width) solid var(--fs-focus-color);
3644
+ outline-offset: var(--fs-focus-offset);
3645
+ }
3646
+ }
3647
+ /* stylelint-disable declaration-block-single-line-max-declarations */
3648
+ @layer components {
3649
+ .fs-list-group {
3650
+ display: flex;
3651
+ flex-direction: column;
3652
+ padding: 0;
3653
+ margin: 0;
3654
+ list-style: none;
3655
+ border: 1px solid var(--fs-color-border);
3656
+ border-radius: var(--fs-radius-md);
3657
+ }
3658
+ .fs-list-group-item {
3659
+ position: relative;
3660
+ display: block;
3661
+ padding: var(--fs-space-3) var(--fs-space-4);
3662
+ color: var(--fs-color-text);
3663
+ background: var(--fs-color-surface);
3664
+ border-block-end: 1px solid var(--fs-color-border);
3665
+ }
3666
+ .fs-list-group-item:last-child {
3667
+ border-block-end: 0;
3668
+ }
3669
+ button.fs-list-group-item, a.fs-list-group-item {
3670
+ width: 100%;
3671
+ text-align: start;
3672
+ cursor: pointer;
3673
+ }
3674
+ .fs-list-group-item:hover {
3675
+ background: var(--fs-color-subtle);
3676
+ }
3677
+ .fs-list-group-item.is-active {
3678
+ color: var(--fs-color-on-primary);
3679
+ background: var(--fs-color-primary);
3680
+ }
3681
+ }
3682
+ @layer components {
3683
+ .fs-code {
3684
+ padding: 0.125em 0.35em;
3685
+ color: var(--fs-color-danger);
3686
+ background: var(--fs-color-subtle);
3687
+ border-radius: var(--fs-radius-sm);
3688
+ }
3689
+ .fs-pre {
3690
+ display: block;
3691
+ max-width: 100%;
3692
+ padding: var(--fs-space-4);
3693
+ overflow: auto;
3694
+ color: var(--fs-color-text);
3695
+ background: var(--fs-color-subtle);
3696
+ border: 1px solid var(--fs-color-border);
3697
+ border-radius: var(--fs-radius-md);
3698
+ }
3699
+ }
3700
+ /* stylelint-disable declaration-block-single-line-max-declarations */
3701
+ @layer components {
3702
+ .fs-ratio {
3703
+ position: relative;
3704
+ width: 100%;
3705
+ }
3706
+ .fs-ratio::before {
3707
+ display: block;
3708
+ padding-top: var(--fs-ratio, 56.25%);
3709
+ content: "";
3710
+ }
3711
+ .fs-ratio > * {
3712
+ position: absolute;
3713
+ inset: 0;
3714
+ width: 100%;
3715
+ height: 100%;
3716
+ object-fit: cover;
3717
+ }
3718
+ .fs-ratio-1x1 {
3719
+ --fs-ratio: 100%;
3720
+ }
3721
+ .fs-ratio-4x3 {
3722
+ --fs-ratio: 75%;
3723
+ }
3724
+ .fs-ratio-16x9 {
3725
+ --fs-ratio: 56.25%;
3726
+ }
3727
+ .fs-ratio-21x9 {
3728
+ --fs-ratio: 42.857%;
3729
+ }
3730
+ }
3731
+ /* stylelint-disable declaration-block-single-line-max-declarations */
3732
+ @layer components {
3733
+ .fs-icon-link {
3734
+ display: inline-flex;
3735
+ gap: 0.5em;
3736
+ align-items: center;
3737
+ }
3738
+ .fs-icon-link svg {
3739
+ width: 1em;
3740
+ height: 1em;
3741
+ flex: 0 0 auto;
3742
+ }
3743
+ .fs-icon-link:hover svg {
3744
+ transform: translateX(0.15em);
3745
+ }
3746
+ @media (prefers-reduced-motion: reduce) {
3747
+ .fs-icon-link svg {
3748
+ transition: none;
3749
+ }
3750
+ }
3751
+ }
3752
+ /* stylelint-disable declaration-block-single-line-max-declarations */
3753
+ @layer components {
3754
+ .fs-placeholder {
3755
+ display: inline-block;
3756
+ min-height: 1em;
3757
+ vertical-align: middle;
3758
+ cursor: wait;
3759
+ background: currentcolor;
3760
+ opacity: 0.18;
3761
+ }
3762
+ .fs-placeholder-glow {
3763
+ animation: fs-placeholder-glow 1.5s ease-in-out infinite;
3764
+ }
3765
+ .fs-placeholder-wave {
3766
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent), currentcolor;
3767
+ background-size: 200% 100%;
3768
+ animation: fs-placeholder-wave 1.5s linear infinite;
3769
+ }
3770
+ .fs-placeholder-btn {
3771
+ width: 6rem;
3772
+ height: 2.5rem;
3773
+ border-radius: var(--fs-radius-sm);
3774
+ }
3775
+ @keyframes fs-placeholder-glow {
3776
+ 50% {
3777
+ opacity: 0.08;
3778
+ }
3779
+ }
3780
+ @keyframes fs-placeholder-wave {
3781
+ to {
3782
+ background-position: -200% 0;
3783
+ }
3784
+ }
3785
+ @media (prefers-reduced-motion: reduce) {
3786
+ .fs-placeholder-glow, .fs-placeholder-wave {
3787
+ animation: none;
3788
+ }
3789
+ }
3790
+ }
3791
+ /* stylelint-disable declaration-block-single-line-max-declarations */
3792
+ @layer components {
3793
+ .fs-progress {
3794
+ display: flex;
3795
+ height: 0.75rem;
3796
+ overflow: hidden;
3797
+ background: var(--fs-color-subtle);
3798
+ border-radius: 999px;
3799
+ }
3800
+ .fs-progress-bar {
3801
+ display: flex;
3802
+ align-items: center;
3803
+ justify-content: center;
3804
+ color: var(--fs-color-on-primary);
3805
+ background: var(--fs-color-primary);
3806
+ transition: width var(--fs-motion-duration-normal) var(--fs-motion-ease-standard);
3807
+ }
3808
+ .fs-progress-bar-striped {
3809
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%);
3810
+ background-size: 1rem 1rem;
3811
+ }
3812
+ @media (prefers-reduced-motion: reduce) {
3813
+ .fs-progress-bar {
3814
+ transition: none;
3815
+ }
3816
+ }
3817
+ }
3818
+ /* stylelint-disable declaration-block-single-line-max-declarations */
3819
+ @layer components {
3820
+ [data-fs-scrollspy] .is-active {
3821
+ color: var(--fs-color-primary);
3822
+ font-weight: 600;
3823
+ }
3824
+ .fs-scrollspy-nav {
3825
+ position: sticky;
3826
+ inset-block-start: var(--fs-space-4);
3827
+ }
3828
+ }
3355
3829
  @layer tokens {
3356
3830
  [data-fs-brand=violet] {
3357
3831
  --fs-color-primary: #6d28d9;
@@ -3447,7 +3921,8 @@
3447
3921
  }
3448
3922
  }
3449
3923
  @layer tokens {
3450
- [data-theme=dark] {
3924
+ [data-theme=dark],
3925
+ [data-fs-theme=dark] {
3451
3926
  --fs-color-text: #f1f3f4;
3452
3927
  --fs-color-muted: #bdc1c6;
3453
3928
  --fs-color-border: #3c4043;
@@ -3494,7 +3969,8 @@
3494
3969
  --fs-feedback-info-bg: rgb(35.0058091619, 49.6887857769, 78.5757788254);
3495
3970
  }
3496
3971
  @supports (color: oklch(0% 0 0deg)) {
3497
- [data-theme=dark] {
3972
+ [data-theme=dark],
3973
+ [data-fs-theme=dark] {
3498
3974
  --fs-color-text: oklch(96.2913383165% 0.002529697 228.7848682695deg);
3499
3975
  --fs-color-muted: oklch(80.9268110646% 0.0083071608 253.8653061211deg);
3500
3976
  --fs-color-border: oklch(36.8827622528% 0.0074489239 240.018838067deg);
@@ -3538,5 +4014,37 @@
3538
4014
  --fs-feedback-info-bg: oklch(31.7574919059% 0.0556228738 263.0598185246deg);
3539
4015
  }
3540
4016
  }
4017
+ @media (prefers-color-scheme: dark) {
4018
+ [data-fs-theme=auto] {
4019
+ --fs-color-text: #f1f3f4;
4020
+ --fs-color-muted: #bdc1c6;
4021
+ --fs-color-border: #3c4043;
4022
+ --fs-color-surface: #202124;
4023
+ --fs-color-subtle: #2b2c2f;
4024
+ --fs-color-bg-surface: var(--fs-color-surface);
4025
+ --fs-color-bg-subtle: var(--fs-color-subtle);
4026
+ --fs-color-surface-raised: var(--fs-color-surface);
4027
+ --fs-color-surface-interactive: var(--fs-color-subtle);
4028
+ --fs-color-text-primary: var(--fs-color-text);
4029
+ --fs-color-text-muted: var(--fs-color-muted);
4030
+ --fs-color-border-default: var(--fs-color-border);
4031
+ --fs-color-focus: var(--fs-color-primary);
4032
+ --fs-tooltip-bg: #f8fafc;
4033
+ --fs-tooltip-text: #1e293b;
4034
+ }
4035
+ }
4036
+ @media (forced-colors: active) {
4037
+ :root,
4038
+ [data-theme=dark],
4039
+ [data-fs-theme=light],
4040
+ [data-fs-theme=dark],
4041
+ [data-fs-theme=auto] {
4042
+ --fs-color-border: CanvasText;
4043
+ --fs-color-text: CanvasText;
4044
+ --fs-color-surface: Canvas;
4045
+ --fs-color-subtle: Canvas;
4046
+ --fs-focus-color: Highlight;
4047
+ }
4048
+ }
3541
4049
  }
3542
4050
  /*# sourceMappingURL=components.css.map */