fokus-styles 2.5.0 → 2.6.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 (177) hide show
  1. package/package.json +17 -15
  2. package/CHANGELOG.md +0 -940
  3. package/dist/css/components.css.map +0 -1
  4. package/dist/css/components.min.css.map +0 -1
  5. package/dist/css/fokus-components.css.map +0 -1
  6. package/dist/css/fokus-components.min.css.map +0 -1
  7. package/dist/css/fokus-core.css.map +0 -1
  8. package/dist/css/fokus-core.min.css.map +0 -1
  9. package/dist/css/fokus-dark.css.map +0 -1
  10. package/dist/css/fokus-dark.min.css.map +0 -1
  11. package/dist/css/fokus-rtl.css.map +0 -1
  12. package/dist/css/fokus-rtl.min.css.map +0 -1
  13. package/dist/css/fokus-utilities.css.map +0 -1
  14. package/dist/css/fokus-utilities.min.css.map +0 -1
  15. package/dist/css/fokus.css.map +0 -1
  16. package/dist/css/fokus.min.css.map +0 -1
  17. package/dist/css/fonts.css.map +0 -1
  18. package/dist/css/fonts.min.css.map +0 -1
  19. package/dist/css/forms.css.map +0 -1
  20. package/dist/css/forms.min.css.map +0 -1
  21. package/dist/css/helpers.css.map +0 -1
  22. package/dist/css/helpers.min.css.map +0 -1
  23. package/dist/css/layout.css.map +0 -1
  24. package/dist/css/layout.min.css.map +0 -1
  25. package/dist/js/fokus.js.map +0 -7
  26. package/dist/js/fokus.min.js.map +0 -7
  27. package/docs/README.md +0 -86
  28. package/docs/comparison.md +0 -124
  29. package/docs/components/accordion.md +0 -104
  30. package/docs/components/alert-dialog.md +0 -99
  31. package/docs/components/alert.md +0 -104
  32. package/docs/components/avatar.md +0 -13
  33. package/docs/components/badge.md +0 -101
  34. package/docs/components/breadcrumb.md +0 -93
  35. package/docs/components/button-group.md +0 -13
  36. package/docs/components/button.md +0 -98
  37. package/docs/components/card.md +0 -111
  38. package/docs/components/carousel.md +0 -167
  39. package/docs/components/checkbox.md +0 -110
  40. package/docs/components/close-button.md +0 -13
  41. package/docs/components/code.md +0 -13
  42. package/docs/components/collapse.md +0 -78
  43. package/docs/components/combobox.md +0 -123
  44. package/docs/components/command-palette.md +0 -131
  45. package/docs/components/datatable.md +0 -173
  46. package/docs/components/datepicker.md +0 -137
  47. package/docs/components/divider.md +0 -57
  48. package/docs/components/dropdown.md +0 -103
  49. package/docs/components/empty-state.md +0 -65
  50. package/docs/components/file-upload-advanced.md +0 -116
  51. package/docs/components/file-upload.md +0 -93
  52. package/docs/components/icon-link.md +0 -13
  53. package/docs/components/input-group.md +0 -73
  54. package/docs/components/input.md +0 -90
  55. package/docs/components/list-group.md +0 -13
  56. package/docs/components/modal.md +0 -120
  57. package/docs/components/navbar.md +0 -74
  58. package/docs/components/nested-menu.md +0 -90
  59. package/docs/components/notification-center.md +0 -116
  60. package/docs/components/offcanvas.md +0 -102
  61. package/docs/components/pagination.md +0 -145
  62. package/docs/components/placeholder.md +0 -13
  63. package/docs/components/popover.md +0 -118
  64. package/docs/components/progress.md +0 -126
  65. package/docs/components/radio.md +0 -80
  66. package/docs/components/range.md +0 -83
  67. package/docs/components/rating.md +0 -91
  68. package/docs/components/ratio.md +0 -13
  69. package/docs/components/responsive.md +0 -19
  70. package/docs/components/scrollspy.md +0 -13
  71. package/docs/components/segmented-control.md +0 -82
  72. package/docs/components/select.md +0 -89
  73. package/docs/components/skeleton.md +0 -70
  74. package/docs/components/stepper.md +0 -107
  75. package/docs/components/switch.md +0 -97
  76. package/docs/components/table.md +0 -90
  77. package/docs/components/tabs.md +0 -104
  78. package/docs/components/tag.md +0 -144
  79. package/docs/components/tile.md +0 -112
  80. package/docs/components/timeline.md +0 -78
  81. package/docs/components/toast.md +0 -108
  82. package/docs/components/tooltip.md +0 -113
  83. package/docs/components/tree-view.md +0 -118
  84. package/docs/contributing/contributing.md +0 -18
  85. package/docs/getting-started/installation.md +0 -70
  86. package/docs/getting-started/usage.md +0 -105
  87. package/docs/guides/accessibility.md +0 -109
  88. package/docs/guides/charts.md +0 -73
  89. package/docs/guides/dark-mode.md +0 -90
  90. package/docs/guides/icons.md +0 -99
  91. package/docs/guides/javascript-api.md +0 -9
  92. package/docs/guides/layout-advanced.md +0 -118
  93. package/docs/guides/migration-clarus-to-fokus.md +0 -48
  94. package/docs/guides/migration-external.md +0 -123
  95. package/docs/guides/migration-v1.md +0 -63
  96. package/docs/guides/print.md +0 -30
  97. package/docs/guides/rtl-and-system-preferences.md +0 -28
  98. package/docs/guides/theming.md +0 -140
  99. package/docs/guides/utility-api.md +0 -9
  100. package/docs/prompts/prompt-plan.md +0 -45
  101. package/docs/reference/accessibility-matrix.md +0 -77
  102. package/docs/reference/browser-support.md +0 -75
  103. package/docs/reference/contrast-report.md +0 -54
  104. package/docs/reference/definitions.md +0 -868
  105. package/docs/reference/design-tokens.md +0 -208
  106. package/docs/reference/scss-architecture.md +0 -227
  107. package/docs/reference/size-baseline.json +0 -34
  108. package/docs/reference/stability.md +0 -89
  109. package/docs/showcase.md +0 -25
  110. package/mockup/README.md +0 -41
  111. package/mockup/assets/carousel-planning.png +0 -0
  112. package/mockup/assets/carousel-workspace.png +0 -0
  113. package/mockup/assets/example-theme.css +0 -19
  114. package/mockup/assets/example-theme.js +0 -11
  115. package/mockup/assets/showcase-contracts.js +0 -84
  116. package/mockup/assets/showcase.css +0 -91
  117. package/mockup/assets/showcase.js +0 -724
  118. package/mockup/content-data.html +0 -9
  119. package/mockup/examples/accordion-tabs-toast.html +0 -149
  120. package/mockup/examples/alert-dialog.html +0 -84
  121. package/mockup/examples/alerts.html +0 -115
  122. package/mockup/examples/badges-alerts.html +0 -109
  123. package/mockup/examples/buttons.html +0 -58
  124. package/mockup/examples/cards.html +0 -132
  125. package/mockup/examples/carousel.html +0 -126
  126. package/mockup/examples/charts.html +0 -102
  127. package/mockup/examples/check-radio-switch.html +0 -620
  128. package/mockup/examples/collapse.html +0 -69
  129. package/mockup/examples/combobox.html +0 -60
  130. package/mockup/examples/command-palette.html +0 -64
  131. package/mockup/examples/datatable.html +0 -113
  132. package/mockup/examples/datepicker.html +0 -62
  133. package/mockup/examples/divider.html +0 -45
  134. package/mockup/examples/dropdown-tooltip.html +0 -77
  135. package/mockup/examples/empty-state.html +0 -56
  136. package/mockup/examples/file-drop.html +0 -74
  137. package/mockup/examples/file-upload-advanced.html +0 -68
  138. package/mockup/examples/forms-advanced.html +0 -77
  139. package/mockup/examples/hover-card.html +0 -86
  140. package/mockup/examples/icons.html +0 -157
  141. package/mockup/examples/input-group.html +0 -74
  142. package/mockup/examples/js-foundation.html +0 -215
  143. package/mockup/examples/layout.html +0 -134
  144. package/mockup/examples/modal-select.html +0 -127
  145. package/mockup/examples/nested-menu.html +0 -73
  146. package/mockup/examples/notification-center.html +0 -86
  147. package/mockup/examples/offcanvas-popover.html +0 -133
  148. package/mockup/examples/pagination-breadcrumbs.html +0 -92
  149. package/mockup/examples/popover.html +0 -81
  150. package/mockup/examples/range.html +0 -69
  151. package/mockup/examples/rating.html +0 -103
  152. package/mockup/examples/segmented-control.html +0 -96
  153. package/mockup/examples/skeletons.html +0 -82
  154. package/mockup/examples/spinner-progress.html +0 -130
  155. package/mockup/examples/stepper.html +0 -119
  156. package/mockup/examples/tables-navbar.html +0 -89
  157. package/mockup/examples/tag.html +0 -115
  158. package/mockup/examples/theming.html +0 -68
  159. package/mockup/examples/tile.html +0 -107
  160. package/mockup/examples/timeline.html +0 -108
  161. package/mockup/examples/toast.html +0 -113
  162. package/mockup/examples/tooltip.html +0 -68
  163. package/mockup/examples/tree-view.html +0 -68
  164. package/mockup/feedback-actions.html +0 -9
  165. package/mockup/forms.html +0 -13
  166. package/mockup/foundations.html +0 -7
  167. package/mockup/kitchen-sink.html +0 -696
  168. package/mockup/navigation-disclosure.html +0 -11
  169. package/mockup/overlays-commands.html +0 -12
  170. package/mockup/templates/README.md +0 -20
  171. package/mockup/templates/admin.html +0 -334
  172. package/mockup/templates/auth.html +0 -234
  173. package/mockup/templates/dashboard.html +0 -442
  174. package/mockup/templates/landing.html +0 -397
  175. package/packages/fokus-icons/package.json +0 -46
  176. package/scripts/migrate-fokus-map.json +0 -1366
  177. package/scripts/migrate-fokus.mjs +0 -97
@@ -1,84 +0,0 @@
1
- window.showcaseContracts = {
2
- layout: {
3
- use: [{ label: "Estrutura de página", text: "Use containers, grid e utilitários de espaçamento para organizar cabeçalho, conteúdo principal e colunas responsivas." }, { label: "Evite", text: "não use classes de grid para comunicar significado; a ordem do DOM deve continuar lógica em telas pequenas." }],
4
- api: [{ label: ".fs-container / .fs-container-fluid", code: true, text: "limitam a largura de leitura ou ocupam toda a viewport." }, { label: ".fs-row / .fs-col-*", code: true, text: "criam linhas e colunas responsivas; combine os tamanhos por breakpoint." }, { label: ".fs-u-gap-* / .fs-u-p-* / .fs-u-m-*", code: true, text: "ajustam espaçamento sem criar CSS local." }],
5
- a11y: [{ label: "Ordem", text: "mantenha a leitura e o foco no DOM na mesma sequência do conteúdo visual." }, { label: "Responsividade", text: "não esconda informação somente porque a grade mudou de coluna." }],
6
- states: [{ label: "Breakpoints", text: "valide uma, duas e várias colunas nos limites de viewport." }, { label: "Densidade", text: "confira gutters, overflow horizontal e reflow de ações." }],
7
- },
8
- theming: {
9
- use: [{ label: "Tema de produto", text: "Use para alternar claro/escuro ou aplicar uma marca sem sobrescrever cores de componentes isoladamente." }],
10
- api: [{ label: "data-fs-theme=\"light|dark|auto\"", code: true, text: "controla o color mode canônico em html ou em um contêiner." }, { label: "data-theme=\"dark\"", code: true, text: "permanece como compatibilidade para consumidores existentes." }, { label: "data-fs-brand=\"violet|corporate|vibrant\"", code: true, text: "seleciona uma marca publicada; pode ser combinado com data-fs-theme." }, { label: "--fs-color-*", code: true, text: "tokens semânticos consumidos pelos componentes; evite trocar cores literais em cada componente." }],
11
- a11y: [{ label: "Contraste", text: "revalide contraste após criar marca ou sobrescrever token." }, { label: "Preferência", text: "não alterne tema sem controle explícito e persistência coerente para a pessoa usuária." }],
12
- states: [{ label: "Claro e escuro", text: "teste superfície, texto, borda, foco e componentes sobrepostos em ambos." }],
13
- },
14
- icons: {
15
- use: [{ label: "Ações reconhecíveis", text: "Use ícones para reforçar rótulos de ação ou economizar espaço em controles com nome acessível." }],
16
- api: [{ label: ".fs-icon", code: true, text: "normaliza tamanho, alinhamento e currentColor para SVG inline." }, { label: "aria-hidden=\"true\"", code: true, text: "use em ícone decorativo acompanhado por texto." }, { label: "aria-label", code: true, text: "nomeia botão somente de ícone; não aplique no SVG e no botão ao mesmo tempo." }],
17
- a11y: [{ label: "Nome", text: "um ícone que é a única pista da ação precisa de botão/link com nome acessível." }, { label: "Cor", text: "não use apenas cor ou forma do ícone para comunicar estado crítico." }],
18
- states: [{ label: "Interação", text: "valide ícone em hover, focus-visible, disabled e cada tema." }],
19
- },
20
- divider: {
21
- use: [{ label: "Separação sutil", text: "Use entre grupos relacionados de conteúdo, ações ou seções de formulário; não substitui heading." }],
22
- api: [{ label: ".fs-divider", code: true, text: "divisor horizontal com cor e espaçamento do sistema." }, { label: ".fs-divider-vertical", code: true, text: "divisor vertical para grupos em uma mesma linha; teste o reflow em telas pequenas." }, { label: "role=\"separator\"", code: true, text: "use quando o separador tiver significado estrutural além de decoração." }],
23
- a11y: [{ label: "Estrutura", text: "prefira headings e landmarks para separar seções semânticas." }],
24
- states: [{ label: "Responsividade", text: "no layout empilhado, remova ou converta divisores verticais." }],
25
- },
26
- "js-foundation": {
27
- use: [{ label: "Comportamento opcional", text: "Use data-fs para inicializar componentes FokusStyles sem framework e recupere instâncias apenas quando houver ação programática." }],
28
- api: [{ label: "data-fs=\"nome\"", code: true, text: "ativa o auto-init do componente no elemento raiz indicado." }, { label: "FokusStyles.Nome.getInstance(el)", code: true, text: "recupera a instância já inicializada." }, { label: "dispose()", code: true, text: "remove listeners e referências quando o elemento sai da página." }],
29
- a11y: [{ label: "Progressive enhancement", text: "o HTML precisa continuar compreensível quando JavaScript falhar ou estiver indisponível." }],
30
- states: [{ label: "Ciclo de vida", text: "teste auto-init, interação, remoção e reinicialização sem listeners duplicados." }],
31
- },
32
- button: {
33
- use: [{ label: "Ação", text: "Use button para salvar, confirmar, abrir painel ou executar operação; use link para navegação." }],
34
- api: [{ label: ".fs-btn", code: true, text: "classe-base para botão ou link com aparência de botão." }, { label: ".fs-btn-primary|secondary|success|warning|danger|info", code: true, text: "define a intenção visual da ação." }, { label: ".fs-btn-outline-* / .fs-btn-sm / .fs-btn-lg / disabled", code: true, text: "cria contorno, ajusta densidade ou desabilita o controle." }],
35
- a11y: [{ label: "Semântica", text: "use button nativo para ações e mantenha texto de ação específico." }, { label: "Desabilitado", text: "em links, aria-disabled não bloqueia clique sozinho; remova a ação programaticamente." }],
36
- states: [{ label: "Validação", text: "teste hover, focus-visible, active, loading e disabled em claro e escuro." }],
37
- },
38
- badge: {
39
- use: [{ label: "Status curto", text: "Use para categoria, contagem ou estado resumido próximo ao item que descreve." }],
40
- api: [{ label: ".fs-badge", code: true, text: "rótulo-base compacto." }, { label: ".fs-badge-{primary|secondary|success|warning|danger|info}", code: true, text: "variante semântica de cor." }],
41
- a11y: [{ label: "Texto", text: "não comunique estado apenas por cor; inclua rótulo como Ativo, Erro ou 3 notificações." }],
42
- states: [{ label: "Contraste", text: "valide cada variante e números longos em ambos os temas." }],
43
- },
44
- alert: {
45
- use: [{ label: "Feedback contextual", text: "Use para sucesso, aviso, erro ou informação persistente relacionada à região afetada." }],
46
- api: [{ label: ".fs-alert", code: true, text: "contêiner-base da mensagem persistente." }, { label: ".fs-alert-{primary|secondary|success|warning|danger|info}", code: true, text: "seleciona intenção visual." }, { label: ".fs-alert-group / .fs-alert-inline", code: true, text: "organizam mensagens relacionadas e versões compactas." }, { label: ".fs-alert-icon / -content / -heading / -text", code: true, text: "organizam ícone, título e descrição opcionais." }, { label: ".fs-alert-actions / -link / -close", code: true, text: "compõem ações, link contextual e fechamento visual manual." }],
47
- a11y: [{ label: "Urgência", text: "use role=alert somente para mensagem urgente e role=status para atualização calma; o componente não injeta ARIA nem move foco." }],
48
- states: [{ label: "Conteúdo", text: "teste grupo, inline, loading com aria-busy, ícone decorativo, ações, fechamento manual, forced colors e telas estreitas." }],
49
- },
50
- input: { use: [{ label: "Dado curto", text: "Use para texto, e-mail, senha ou número quando a pessoa deve digitar um valor identificável." }], api: [{ label: ".fs-form-control", code: true, text: "estiliza input e textarea nativos." }, { label: ".is-valid / .is-invalid", code: true, text: "aplicam feedback visual de validação." }, { label: "disabled / readonly / aria-describedby", code: true, text: "controlam disponibilidade, edição e associação com ajuda ou erro." }], a11y: [{ label: "Rótulo", text: "associe label ao id; placeholder não substitui o nome persistente." }, { label: "Erro", text: "conecte ajuda e mensagem de erro com aria-describedby." }], states: [{ label: "Validação", text: "teste foco, readonly, disabled, sucesso e erro com mensagem longa." }] },
51
- select: { use: [{ label: "Opções conhecidas", text: "Use select nativo para listas curtas; use Combobox quando a busca reduzir esforço." }], api: [{ label: ".fs-select", code: true, text: "aplica acabamento FokusStyles ao select nativo." }, { label: "required / disabled / multiple", code: true, text: "mantêm comportamento nativo de obrigatoriedade, indisponibilidade e múltipla escolha." }], a11y: [{ label: "Nome", text: "forneça label visível e não simule select com div sem necessidade." }], states: [{ label: "Opções", text: "teste placeholder, selecionado, disabled, erro e teclado nativo." }] },
52
- "input-group": { use: [{ label: "Entrada composta", text: "Use somente para prefixo, sufixo ou ação que pertença ao mesmo valor digitado." }], api: [{ label: ".fs-input-group", code: true, text: "alinha controle, addon e botão como uma única unidade visual." }, { label: ".fs-input-group-text", code: true, text: "prefixo ou sufixo textual/ícone não editável." }], a11y: [{ label: "Finalidade", text: "o campo continua precisando de label próprio; ícones de ação precisam de nome acessível." }], states: [{ label: "Integração", text: "teste foco e validação no controle, não no addon decorativo." }] },
53
- "check-radio-switch": { use: [{ label: "Escolha", text: "Checkbox para opções independentes, radio para uma escolha e switch para preferência com efeito imediato." }], api: [{ label: ".fs-check / .fs-radio / .fs-switch", code: true, text: "estilizam controles nativos sem trocar sua semântica." }, { label: "checked / indeterminate / disabled", code: true, text: "estados nativos que a aparência acompanha." }], a11y: [{ label: "Grupo", text: "use fieldset e legend para opções relacionadas e label associado a cada controle." }], states: [{ label: "Seleção", text: "teste marcado, indeterminado, erro, disabled e ativação por Espaço." }] },
54
- range: { use: [{ label: "Valor aproximado", text: "Use para faixa contínua quando arrastar é mais útil que digitar precisão absoluta." }], api: [{ label: "input[type=range]", code: true, text: "controle nativo estilizado; defina min, max, step e value." }, { label: "aria-valuetext", code: true, text: "fornece valor compreensível quando o número puro não basta." }], a11y: [{ label: "Valor", text: "inclua label, limites e resultado textual atualizado quando necessário." }], states: [{ label: "Extremos", text: "teste mínimo, máximo, step, teclado e disabled." }] },
55
- "segmented-control": { use: [{ label: "Modo exclusivo", text: "Use para alternar rapidamente entre poucas visões ou modos relacionados." }], api: [{ label: ".fs-segmented-control", code: true, text: "contêiner visual das opções." }, { label: "input[type=radio]", code: true, text: "mantém exclusividade e estado nativos." }], a11y: [{ label: "Semântica", text: "use radio para modos exclusivos; use tabs apenas quando cada opção revela painel associado." }], states: [{ label: "Opções", text: "teste selecionado, foco, ícone e disabled." }] },
56
- rating: { use: [{ label: "Escala familiar", text: "Use para avaliação ordinal curta, expondo também o valor textual." }], api: [{ label: ".fs-rating", code: true, text: "contêiner da escala." }, { label: "data-rating / input[type=radio]", code: true, text: "configuram valor inicial e escolha acessível." }], a11y: [{ label: "Instrução", text: "explique a escala e permita alteração por teclado; não dependa só das estrelas." }], states: [{ label: "Valor", text: "teste leitura, edição, meio valor quando suportado e disabled." }] },
57
- datepicker: { use: [{ label: "Data e hora", text: "Prefira controles nativos para preservar suporte de plataforma e teclado." }], api: [{ label: "input[type=date] / input[type=time]", code: true, text: "campos nativos com acabamento FokusStyles." }, { label: "min / max / required / disabled", code: true, text: "restringem intervalo e disponibilidade." }], a11y: [{ label: "Formato", text: "mantenha label e descreva formato apenas quando necessário; não substitua teclado nativo." }], states: [{ label: "Limites", text: "teste valor inválido, mínimo, máximo, erro e disabled." }] },
58
- combobox: { use: [{ label: "Busca em opções", text: "Use quando filtrar uma lista maior reduz o esforço sem perder uma escolha explícita." }], api: [{ label: ".fs-combobox + data-fs=\"combobox\"", code: true, text: "inicializa filtro, lista e seleção." }, { label: "data-fs-combobox-input / -listbox", code: true, text: "identificam campo e lista da composição." }], a11y: [{ label: "ARIA", text: "preserve role=combobox, aria-expanded, aria-controls e active descendant geridos pelo componente." }], states: [{ label: "Consulta", text: "teste fechado, aberto, filtrado, vazio, teclado e disabled." }] },
59
- "file-upload": { use: [{ label: "Envio com feedback", text: "Use para fila, progresso, erro e remoção de arquivos; mantenha input nativo como base." }], api: [{ label: ".fs-file-upload", code: true, text: "contêiner do fluxo avançado." }, { label: "accept / multiple / data-fs", code: true, text: "restringem tipos, permitem múltiplos arquivos e inicializam comportamento." }], a11y: [{ label: "Status", text: "o input precisa ser alcançável e progresso, erro e remoção devem ser anunciados." }], states: [{ label: "Arquivo", text: "teste clique, drop, múltiplos, carregando, erro e remoção." }] },
60
- "file-drop": { use: [{ label: "Envio simples", text: "Use para selecionar ou arrastar um único arquivo em formulários curtos." }], api: [{ label: ".fs-file-drop", code: true, text: "área visual de drop associada ao input[type=file]." }, { label: "accept", code: true, text: "sugere os formatos aceitos; valide o tipo também no servidor." }], a11y: [{ label: "Alternativa", text: "a área de drop não substitui o input acionável por teclado." }], states: [{ label: "Feedback", text: "teste arrastar, arquivo selecionado e erro de formato." }] },
61
- tag: { use: [{ label: "Filtro ou seleção", text: "Use para itens discretos como categoria, filtro aplicado ou pessoa selecionada." }], api: [{ label: ".fs-tag", code: true, text: "estrutura-base da etiqueta." }, { label: ".fs-tag-{primary|secondary|success|warning|danger|info}", code: true, text: "variante semântica." }, { label: ".fs-tag-remove", code: true, text: "botão opcional de remoção." }], a11y: [{ label: "Remoção", text: "o botão precisa nomear a tag, por exemplo aria-label=\"Remover Design\"." }], states: [{ label: "Variações", text: "teste removível, disabled, rótulo longo e foco." }] },
62
- "empty-state": { use: [{ label: "Sem conteúdo", text: "Use para primeira utilização, busca sem resultado ou região sem dados." }], api: [{ label: ".fs-empty-state", code: true, text: "contêiner centralizado." }, { label: ".fs-empty-state-icon / -title / -text / -action", code: true, text: "organizam ilustração, mensagem e CTA." }], a11y: [{ label: "Próximo passo", text: "título e ação devem explicar a situação fora do contexto visual." }], states: [{ label: "Cenário", text: "valide sem dados, sem resultados e carregamento concluído." }] },
63
- skeleton: { use: [{ label: "Carregamento previsível", text: "Use para reservar espaço de conteúdo temporário e reduzir salto de layout." }], api: [{ label: ".fs-skeleton", code: true, text: "bloco-base." }, { label: ".fs-skeleton-text / -avatar / -button / -card", code: true, text: "formas prontas para estruturas comuns." }], a11y: [{ label: "Decoração", text: "oculte o skeleton de leitores de tela e anuncie carregamento na região adequada." }], states: [{ label: "Movimento", text: "teste animação reduzida, conteúdo lento e substituição pelo resultado." }] },
64
- progress: { use: [{ label: "Operação em curso", text: "Use spinner para espera indeterminada e progress para avanço mensurável." }], api: [{ label: ".fs-spinner / .fs-spinner-sm / .fs-spinner-lg", code: true, text: "indicador indeterminado." }, { label: ".fs-progress > .fs-progress-bar", code: true, text: "trilha e preenchimento." }, { label: "role=\"progressbar\" + aria-valuenow/min/max", code: true, text: "expõe valor de progresso." }], a11y: [{ label: "Status", text: "informe o que está acontecendo e valor atual quando houver." }], states: [{ label: "Operação", text: "teste indeterminado, 0%, intermediário, concluído e erro." }] },
65
- navbar: { use: [{ label: "Navegação global", text: "Use para destinos principais do produto, não para ações locais." }], api: [{ label: ".fs-navbar / .fs-navbar-brand / .fs-navbar-nav", code: true, text: "estrutura de marca e links." }, { label: ".fs-navbar-toggler + data-fs-toggle=\"navbar\" + data-fs-target", code: true, text: "ativa colapso no viewport compacto e mantém aria-expanded." }], a11y: [{ label: "Destino atual", text: "use aria-current=\"page\" no link ativo e nomeie o nav." }], states: [{ label: "Compacto", text: "teste aberto, fechado, teclado e foco no menu móvel." }] },
66
- breadcrumb: { use: [{ label: "Hierarquia", text: "Use para mostrar o caminho até a página atual em estruturas profundas." }], api: [{ label: ".fs-breadcrumb > .fs-breadcrumb-item", code: true, text: "lista de níveis; o último representa a página atual." }, { label: "aria-current=\"page\"", code: true, text: "marca o item atual sem link." }], a11y: [{ label: "Navegação", text: "envolva em nav com aria-label=\"Breadcrumb\"." }], states: [{ label: "Comprimento", text: "teste rótulos longos e reflow em telas pequenas." }] },
67
- pagination: { use: [{ label: "Coleção paginada", text: "Use quando resultados são divididos em páginas e a pessoa precisa mudar de intervalo." }], api: [{ label: ".fs-pagination / .fs-page-item / .fs-page-link", code: true, text: "estrutura da lista de páginas." }, { label: ".is-active / .is-disabled", code: true, text: "página atual e limite indisponível." }], a11y: [{ label: "Nomes", text: "use aria-label no nav e aria-current=\"page\" na página atual." }], states: [{ label: "Limites", text: "teste primeira, última, ativa, disabled e foco." }] },
68
- accordion: { use: [{ label: "Detalhe sob demanda", text: "Use para agrupar seções independentes e reduzir densidade inicial da página." }], api: [{ label: ".fs-accordion + data-fs=\"accordion\"", code: true, text: "contêiner que inicializa os painéis." }, { label: ".fs-accordion-button / .fs-accordion-collapse", code: true, text: "gatilho e região expansível de cada item." }, { label: "data-multiple=\"true\"", code: true, text: "permite vários painéis abertos; sem ele, abrir um fecha os demais." }], a11y: [{ label: "Semântica", text: "o componente sincroniza aria-expanded, aria-controls e região nomeada." }], states: [{ label: "Painel", text: "teste aberto inicial, exclusivo, múltiplo, teclado e movimento reduzido." }] },
69
- tabs: { use: [{ label: "Visões pares", text: "Use para trocar painéis relacionados sem deixar a página; cada aba precisa de um conteúdo associado." }], api: [{ label: ".fs-tabs + data-fs=\"tabs\"", code: true, text: "lista de abas e auto-init." }, { label: ".fs-tab-button / .fs-tab-panel", code: true, text: "gatilho e painel correspondentes." }, { label: "data-fs-tab-target=\"#painel\"", code: true, text: "liga botão ao painel por id." }], a11y: [{ label: "Padrão Tabs", text: "roles tablist, tab e tabpanel, aria-selected e setas são sincronizados." }], states: [{ label: "Navegação", text: "teste ativa, foco, ArrowLeft/Right, Home/End e painel vazio." }] },
70
- collapse: { use: [{ label: "Conteúdo adicional", text: "Use para mostrar mais detalhes de uma única região sem a semântica de grupo do Accordion." }], api: [{ label: "data-fs=\"collapse\" + data-fs-target=\"#id\"", code: true, text: "gatilho e destino da expansão." }, { label: ".fs-collapse", code: true, text: "painel com recorte necessário à animação." }, { label: "aria-expanded=\"true\"", code: true, text: "define o estado inicial aberto." }], a11y: [{ label: "Estado", text: "aria-expanded e aria-controls são atualizados automaticamente." }], states: [{ label: "Transição", text: "teste aberto, fechado, conteúdo alto e prefers-reduced-motion." }] },
71
- stepper: { use: [{ label: "Progresso sequencial", text: "Use para comunicar etapas de um processo, não para navegar livremente entre conteúdos." }], api: [{ label: ".fs-stepper / .fs-step", code: true, text: "estrutura da sequência." }, { label: ".is-active / .is-completed / .is-error", code: true, text: "marcam etapa atual, concluída e com falha." }], a11y: [{ label: "Estado textual", text: "inclua rótulo e status compreensível; cor do marcador não basta." }], states: [{ label: "Fluxo", text: "teste pendente, atual, concluída, erro e reflow compacto." }] },
72
- "nested-menu": { use: [{ label: "Navegação hierárquica", text: "Use para poucos níveis de destinos relacionados; não esconda arquitetura complexa em menus profundos." }], api: [{ label: ".fs-nested-menu + data-fs=\"nested-menu\"", code: true, text: "raiz e auto-init." }, { label: "[data-fs-nested-menu-toggle] / [data-fs-nested-menu-submenu]", code: true, text: "identificam gatilho e submenu." }], a11y: [{ label: "Expansão", text: "o toggle precisa de nome e aria-expanded atualizado; preserve Escape e foco." }], states: [{ label: "Subnível", text: "teste aberto, fechado, item ativo, teclado e clique externo." }] },
73
- "tree-view": { use: [{ label: "Estrutura aninhada", text: "Use para arquivos, permissões ou categorias com relação pai-filho explícita." }], api: [{ label: ".fs-tree / .fs-tree-item", code: true, text: "lista e nó da árvore." }, { label: ".fs-tree-toggle / .fs-tree-children", code: true, text: "controle de expansão e grupo filho." }], a11y: [{ label: "Hierarquia", text: "mantenha rótulos, níveis e estado expandido disponíveis; controles precisam de nome." }], states: [{ label: "Nó", text: "teste expandido, recolhido, selecionado, foco e nomes longos." }] },
74
- dropdown: { use: [{ label: "Ações contextuais", text: "Use para agrupar poucas ações secundárias ligadas a um gatilho." }], api: [{ label: "data-fs=\"dropdown\"", code: true, text: "inicializa o grupo." }, { label: "[data-fs-dropdown-toggle] / .fs-dropdown-menu", code: true, text: "gatilho e menu." }], a11y: [{ label: "Foco", text: "aria-expanded, Escape e retorno de foco são geridos; cada item precisa de texto claro." }], states: [{ label: "Menu", text: "teste aberto, fechado, teclado, borda de viewport e disabled." }] },
75
- tooltip: { use: [{ label: "Dica curta", text: "Use para explicar ícone ou termo; não esconda instrução necessária exclusivamente no hover." }], api: [{ label: "data-fs=\"tooltip\" + title/data-title", code: true, text: "inicializa e fornece o texto da dica." }, { label: "data-placement + data-show-delay/data-hide-delay", code: true, text: "define posição e atrasos opcionais." }], a11y: [{ label: "Alternativa", text: "a dica aparece por foco, usa aria-describedby e não é a única fonte de informação essencial." }], states: [{ label: "Posição", text: "teste hover, foco, Escape, touch, fallback, RTL, viewport e conteúdo longo." }] },
76
- "hover-card": { use: [{ label: "Prévia rica", text: "Use para contexto adicional associado a link ou botão, sem interromper a tarefa principal." }], api: [{ label: "data-fs=\"hover-card\"", code: true, text: "inicializa o gatilho." }, { label: "data-fs-hover-card-content / -placement", code: true, text: "define conteúdo e posição." }], a11y: [{ label: "Foco", text: "o conteúdo deve poder ser alcançado por foco quando contiver ações." }], states: [{ label: "Sobreposição", text: "teste hover, foco, atraso, Escape e limite da viewport." }] },
77
- popover: { use: [{ label: "Informação ou ação curta", text: "Use para conteúdo acionado explicitamente; prefira Modal para tarefa extensa." }], api: [{ label: "data-fs=\"popover\" / data-fs-target", code: true, text: "inicializa o gatilho e associa o painel." }, { label: "data-trigger / data-placement / data-align", code: true, text: "configuram interação, posição e alinhamento." }, { label: ".fs-popover-icon / -heading / -text / -close", code: true, text: "slots opcionais para conteúdo rico." }], a11y: [{ label: "Controle", text: "aria-expanded e aria-controls acompanham o gatilho; Escape devolve foco e Popover não cria focus trap." }], states: [{ label: "Visibilidade", text: "teste aberto, fechado, foco interno, clique externo, hover, fallback de viewport e RTL." }] },
78
- offcanvas: { use: [{ label: "Painel lateral", text: "Use para navegação, filtros ou contexto secundário sem abandonar a página." }], api: [{ label: "data-fs=\"offcanvas\" + data-fs-target=\"#id\"", code: true, text: "gatilho e painel." }, { label: ".fs-offcanvas / .fs-offcanvas-start|end", code: true, text: "estrutura e lado de entrada." }], a11y: [{ label: "Diálogo", text: "foco é contido no painel e Escape o fecha; título deve nomear o contexto." }], states: [{ label: "Painel", text: "teste aberto, backdrop, Escape, foco e viewport estreito." }] },
79
- modal: { use: [{ label: "Tarefa concentrada", text: "Use para confirmação, formulário curto ou detalhe que exige atenção temporária." }], api: [{ label: "data-fs=\"modal\" + data-fs-target=\"#id\"", code: true, text: "gatilho e diálogo." }, { label: ".fs-modal / .fs-modal-dialog / .fs-modal-content", code: true, text: "camadas estruturais." }], a11y: [{ label: "Foco", text: "role=dialog, aria-modal, título e retorno de foco são essenciais." }], states: [{ label: "Diálogo", text: "teste abrir, fechar, backdrop, Escape, formulário e conteúdo alto." }] },
80
- "alert-dialog": { use: [{ label: "Confirmação crítica", text: "Use antes de ação destrutiva ou irreversível; mantenha a consequência explícita." }], api: [{ label: "data-fs=\"alert-dialog\"", code: true, text: "inicializa o diálogo de alerta." }, { label: "data-fs-alert-dialog-confirm", code: true, text: "identifica a ação de confirmação." }], a11y: [{ label: "Urgência", text: "use role=alertdialog, texto descritivo e foco inicial na opção segura." }], states: [{ label: "Decisão", text: "teste confirmar, cancelar, Escape quando permitido e foco restaurado." }] },
81
- "command-palette": { use: [{ label: "Atalho de comandos", text: "Use para navegação e ações frequentes de usuários avançados; mantenha alternativas visíveis." }], api: [{ label: "data-fs=\"command-palette\"", code: true, text: "inicializa gatilho e paleta." }, { label: "data-fs-command-palette-input / -list", code: true, text: "identificam busca e resultados." }], a11y: [{ label: "Diálogo", text: "foco, Escape, navegação por setas e anúncio de resultados devem ser preservados." }], states: [{ label: "Busca", text: "teste fechada, aberta, filtrada, vazia, teclado e comandos desabilitados." }] },
82
- toast: { use: [{ label: "Feedback transitório", text: "Use para confirmação breve que não exige decisão imediata; erros críticos devem persistir em contexto." }], api: [{ label: ".fs-toast-container / .fs-toast", code: true, text: "região fixa, empilhada e mensagem flutuante." }, { label: ".fs-toast-icon / -heading / -actions / -progress", code: true, text: "slots opcionais para ícone, título, ações e indicador de tempo." }, { label: "data-fs=\"toast\" / data-delay / data-autohide / data-toast-progress", code: true, text: "inicializam e configuram duração, persistência e progresso." }], a11y: [{ label: "Anúncio", text: "role=status e aria-live=polite são aplicados automaticamente; foco não é movido e hover/foco pausam o timer." }], states: [{ label: "Tempo", text: "teste entrada, auto-dismiss, pausa por hover/foco, progresso, empilhamento, RTL e fechamento manual." }] },
83
- "notification-center": { use: [{ label: "Histórico de notificações", text: "Use quando mensagens precisam ser revisitadas, filtradas ou marcadas como lidas." }], api: [{ label: "data-fs=\"notification-center\"", code: true, text: "inicializa o painel." }, { label: "data-fs-notification-toggle / -list", code: true, text: "gatilho e lista de notificações." }], a11y: [{ label: "Contagem", text: "o botão deve expor contagem e estado expandido; itens precisam de ações nomeadas." }], states: [{ label: "Lista", text: "teste vazia, não lida, lida, aberta, teclado e marcação em lote." }] },
84
- };
@@ -1,91 +0,0 @@
1
- :root {
2
- color: var(--fs-color-text);
3
- background: var(--fs-color-subtle);
4
- color-scheme: light;
5
- }
6
-
7
- html[data-theme="dark"], html[data-fs-theme="dark"] { color-scheme: dark; }
8
-
9
- * { box-sizing: border-box; }
10
-
11
- body {
12
- min-block-size: 100vh;
13
- margin: 0;
14
- color: var(--fs-color-text);
15
- background: var(--fs-color-subtle);
16
- font-family: var(--fs-font-sans, system-ui, sans-serif);
17
- line-height: 1.5;
18
- }
19
-
20
- .showcase-shell { max-width: 1440px; margin: 0 auto; padding: 32px 24px 72px; }
21
- .showcase-hero { max-width: 820px; margin-bottom: 32px; }
22
- .showcase-eyebrow { margin: 0 0 8px; color: var(--fs-color-primary); font-size: .8125rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
23
- .showcase-title { margin: 0; font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1.08; }
24
- .showcase-lead { max-width: 70ch; margin: 16px 0 0; font-size: 1.0625rem; }
25
-
26
- .showcase-toolbar, .showcase-nav { display: flex; flex-wrap: wrap; gap: 8px; }
27
- .showcase-toolbar { margin: 20px 0; }
28
- .showcase-nav { margin: 0 0 32px; padding: 16px 0; border-block: 1px solid var(--fs-color-border); }
29
- .showcase-nav a { padding: 6px 10px; border-radius: var(--fs-radius-sm); color: inherit; text-decoration: none; }
30
- .showcase-nav a:hover, .showcase-nav a:focus-visible { color: var(--fs-color-primary); background: var(--fs-color-surface-alt); outline: none; }
31
-
32
- .showcase-section { margin-top: 32px; padding: 24px; border: 1px solid var(--fs-color-border); border-radius: var(--fs-radius-lg); background: var(--fs-color-surface); box-shadow: var(--fs-shadow-sm); scroll-margin-top: 20px; }
33
- .showcase-section h2 { margin: 0; font-size: 1.5rem; }
34
- .showcase-description { max-width: 80ch; margin: 8px 0 18px; }
35
- .showcase-resources { display: flex; flex-wrap: wrap; gap: 8px 12px; margin: -8px 0 18px; font-size: .8125rem; }
36
- .showcase-resources a { color: var(--fs-color-primary); font-weight: 600; }
37
- .showcase-details { margin: 0 0 20px; }
38
- .showcase-details .fs-accordion-button { padding: 10px 12px; font-size: .8125rem; }
39
- .showcase-detail-body { padding: 12px; font-size: .75rem; }
40
- .showcase-detail-heading { margin: 10px 0 5px; color: var(--fs-color-muted); font-size: .6875rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
41
- .showcase-detail-heading:first-child { margin-top: 0; }
42
- .showcase-detail-list { display: grid; gap: 7px; margin: 0; padding: 0; list-style: none; }
43
- .showcase-detail-list li { line-height: 1.45; }
44
- .showcase-detail-list code { padding: 1px 4px; border-radius: 3px; background: var(--fs-color-surface); font: .6875rem/1.35 var(--fs-font-mono, ui-monospace, monospace); }
45
- .showcase-token { font-family: var(--fs-font-mono, ui-monospace, monospace); font-size: .92em; font-weight: 600; }
46
- .showcase-token-html { color: var(--fs-color-primary); }
47
- .showcase-token-css { color: var(--fs-color-danger); }
48
- .showcase-token-example { color: var(--fs-color-info); }
49
- .showcase-detail-example { color: var(--fs-color-info); }
50
- .showcase-detail-example .showcase-token { color: inherit; }
51
- .showcase-detail-body p { margin: 0; }
52
- .showcase-detail-body p + p { margin-top: 10px; }
53
- .showcase-detail-body p code { display: inline-block; margin: 2px 2px 0 0; padding: 1px 4px; border-radius: 3px; color: var(--fs-color-primary); background: var(--fs-color-surface); font: .6875rem/1.35 var(--fs-font-mono, ui-monospace, monospace); overflow-wrap: anywhere; }
54
- .showcase-detail-body a { color: var(--fs-color-primary); font-weight: 600; }
55
-
56
- /* Tokens de preenchimento mantêm contraste para texto claro em botões. Nos
57
- laboratórios, onde eles aparecem como texto sobre superfícies escuras, use
58
- os tokens textuais semânticos correspondentes. */
59
- html[data-theme="dark"] .showcase-eyebrow,
60
- html[data-theme="dark"] .showcase-resources a,
61
- html[data-theme="dark"] .showcase-nav a:hover,
62
- html[data-theme="dark"] .showcase-nav a:focus-visible,
63
- html[data-theme="dark"] .showcase-detail-body p code,
64
- html[data-theme="dark"] .showcase-detail-body a,
65
- html[data-theme="dark"] .showcase-token-html { color: var(--fs-alert-primary-text); }
66
- html[data-theme="dark"] .showcase-token-css { color: var(--fs-alert-danger-text); }
67
- html[data-theme="dark"] .showcase-token-example,
68
- html[data-theme="dark"] .showcase-detail-example,
69
- html[data-fs-theme="dark"] .showcase-token-example,
70
- html[data-fs-theme="dark"] .showcase-detail-example { color: var(--fs-alert-info-text); }
71
-
72
- .showcase-preview { width: 100%; min-height: 560px; border: 1px solid var(--fs-color-border); border-radius: var(--fs-radius-md); background: var(--fs-color-subtle); }
73
- .showcase-code-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; }
74
- .showcase-code-header h3 { margin: 0; font-size: 1rem; }
75
- .showcase-minimal-header { margin-top: 16px; }
76
- .showcase-minimal-code { max-height: 190px; }
77
- .showcase-copy { min-height: 36px; padding: 6px 10px; border: 1px solid var(--fs-color-border); border-radius: var(--fs-radius-sm); color: var(--fs-color-text); background: var(--fs-color-surface-alt); cursor: pointer; }
78
- .showcase-copy:hover, .showcase-copy:focus-visible { border-color: var(--fs-color-primary); outline: 2px solid var(--fs-color-focus-ring); outline-offset: 2px; }
79
- .showcase-code { max-height: 420px; margin: 8px 0 0; padding: 16px; overflow: auto; border-radius: var(--fs-radius-md); color: var(--fs-color-text-inverse, #fff); background: var(--fs-color-code, #17202a); font: .8125rem/1.5 var(--fs-font-mono, ui-monospace, monospace); white-space: pre; }
80
- .showcase-status { min-height: 1.25rem; margin: 8px 0 0; font-size: .875rem; }
81
-
82
- @media (max-width: 720px) {
83
- .showcase-shell { padding-inline: 16px; }
84
- .showcase-section { padding: 16px; }
85
- .showcase-preview { min-height: 480px; }
86
- }
87
-
88
- @media (prefers-reduced-motion: reduce) {
89
- *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; }
90
- .fs-spinner, .fs-progress-bar-animated, .fs-progress-indeterminate .fs-progress-bar { animation-duration: 1.5s !important; animation-iteration-count: infinite !important; }
91
- }