@codenhub/styles 0.6.0 → 0.8.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 (151) hide show
  1. package/NOTICE +18 -16
  2. package/README.es.md +62 -0
  3. package/README.md +28 -22
  4. package/README.pt-BR.md +62 -0
  5. package/dist/aesthetics/chunky-tile.css +1 -1
  6. package/dist/aesthetics/cyber.css +1 -1
  7. package/dist/aesthetics/glass.css +1 -1
  8. package/dist/aesthetics/index.css +2 -2
  9. package/dist/aesthetics/neobrutalism.css +1 -1
  10. package/dist/aesthetics/pixel.css +1 -1
  11. package/dist/aesthetics/sketch.css +1 -1
  12. package/dist/cli.js +189 -0
  13. package/dist/components.css +2 -2
  14. package/dist/index.css +2 -2
  15. package/dist/index.d.ts +1 -0
  16. package/dist/native.css +2 -2
  17. package/dist/palette.css +1 -1
  18. package/dist/theme.css +2 -2
  19. package/docs/accessibility.md +108 -60
  20. package/docs/changelog/0.1.1.md +1 -0
  21. package/docs/changelog/0.2.0.md +1 -0
  22. package/docs/changelog/0.3.0.md +1 -0
  23. package/docs/changelog/0.4.0.md +1 -0
  24. package/docs/changelog/0.5.0.md +8 -3
  25. package/docs/changelog/0.6.0.md +2 -1
  26. package/docs/changelog/0.7.0.md +50 -0
  27. package/docs/changelog/0.8.0.md +70 -0
  28. package/docs/changelog/index.md +2 -0
  29. package/docs/concepts.md +188 -46
  30. package/docs/es/accessibility.md +169 -0
  31. package/docs/es/concepts.md +212 -0
  32. package/docs/es/index.md +105 -0
  33. package/docs/es/integrating/astro.md +35 -0
  34. package/docs/es/integrating/index.md +75 -0
  35. package/docs/es/integrating/nextjs.md +67 -0
  36. package/docs/es/integrating/svelte.md +45 -0
  37. package/docs/es/integrating/tailwind.md +148 -0
  38. package/docs/es/integrating/vue.md +31 -0
  39. package/docs/es/integrating/without-a-bundler.md +238 -0
  40. package/docs/es/setup.md +188 -0
  41. package/docs/es/usage/aesthetics.md +282 -0
  42. package/docs/es/usage/buttons.md +135 -0
  43. package/docs/es/usage/composing.md +168 -0
  44. package/docs/es/usage/content-and-layout.md +219 -0
  45. package/docs/es/usage/customizing.md +304 -0
  46. package/docs/es/usage/feedback.md +157 -0
  47. package/docs/es/usage/forms.md +256 -0
  48. package/docs/es/usage/index.md +33 -0
  49. package/docs/es/usage/presets.md +92 -0
  50. package/docs/es/usage/solo.md +86 -0
  51. package/docs/es/usage/theming.md +309 -0
  52. package/docs/es/usage/tooltips.md +127 -0
  53. package/docs/index.md +86 -26
  54. package/docs/integrating/astro.md +3 -4
  55. package/docs/integrating/index.md +46 -13
  56. package/docs/integrating/nextjs.md +3 -4
  57. package/docs/integrating/svelte.md +5 -4
  58. package/docs/integrating/tailwind.md +89 -6
  59. package/docs/integrating/vue.md +3 -4
  60. package/docs/integrating/without-a-bundler.md +237 -0
  61. package/docs/pt-BR/accessibility.md +169 -0
  62. package/docs/pt-BR/concepts.md +212 -0
  63. package/docs/pt-BR/index.md +105 -0
  64. package/docs/pt-BR/integrating/astro.md +35 -0
  65. package/docs/pt-BR/integrating/index.md +75 -0
  66. package/docs/pt-BR/integrating/nextjs.md +67 -0
  67. package/docs/pt-BR/integrating/svelte.md +45 -0
  68. package/docs/pt-BR/integrating/tailwind.md +148 -0
  69. package/docs/pt-BR/integrating/vue.md +31 -0
  70. package/docs/pt-BR/integrating/without-a-bundler.md +238 -0
  71. package/docs/pt-BR/setup.md +188 -0
  72. package/docs/pt-BR/usage/aesthetics.md +282 -0
  73. package/docs/pt-BR/usage/buttons.md +135 -0
  74. package/docs/pt-BR/usage/composing.md +168 -0
  75. package/docs/pt-BR/usage/content-and-layout.md +219 -0
  76. package/docs/pt-BR/usage/customizing.md +304 -0
  77. package/docs/pt-BR/usage/feedback.md +157 -0
  78. package/docs/pt-BR/usage/forms.md +256 -0
  79. package/docs/pt-BR/usage/index.md +33 -0
  80. package/docs/pt-BR/usage/presets.md +92 -0
  81. package/docs/pt-BR/usage/solo.md +86 -0
  82. package/docs/pt-BR/usage/theming.md +309 -0
  83. package/docs/pt-BR/usage/tooltips.md +127 -0
  84. package/docs/setup.md +142 -91
  85. package/docs/usage/aesthetics.md +89 -73
  86. package/docs/usage/buttons.md +112 -40
  87. package/docs/usage/composing.md +109 -92
  88. package/docs/usage/content-and-layout.md +160 -125
  89. package/docs/usage/customizing.md +117 -41
  90. package/docs/usage/feedback.md +138 -71
  91. package/docs/usage/forms.md +201 -107
  92. package/docs/usage/index.md +22 -14
  93. package/docs/usage/presets.md +91 -0
  94. package/docs/usage/solo.md +85 -0
  95. package/docs/usage/theming.md +273 -118
  96. package/docs/usage/tooltips.md +90 -49
  97. package/llms-full.txt +2820 -1298
  98. package/llms.txt +24 -22
  99. package/package.json +134 -91
  100. package/{dist/tw → tw}/aesthetics/chunky-tile.css +107 -29
  101. package/{dist/tw → tw}/aesthetics/cyber.css +88 -40
  102. package/{dist/tw → tw}/aesthetics/glass.css +257 -61
  103. package/{dist/tw → tw}/aesthetics/neobrutalism.css +113 -20
  104. package/{dist/tw → tw}/aesthetics/pixel.css +93 -8
  105. package/tw/aesthetics/sketch.css +417 -0
  106. package/{dist/tw → tw}/box.css +105 -9
  107. package/tw/components/button.css +11 -0
  108. package/tw/components/button.rules.css +187 -0
  109. package/tw/components/feedback.css +11 -0
  110. package/{dist/tw/components/feedback.css → tw/components/feedback.rules.css} +136 -32
  111. package/tw/components/form.css +11 -0
  112. package/{dist/tw/components/form.css → tw/components/form.rules.css} +577 -125
  113. package/tw/components/index.css +16 -0
  114. package/tw/components/rules.css +41 -0
  115. package/tw/components/surface.css +11 -0
  116. package/tw/components/surface.rules.css +222 -0
  117. package/tw/components/tooltip.css +11 -0
  118. package/{dist/tw/components/tooltip.css → tw/components/tooltip.rules.css} +43 -27
  119. package/{dist/tw → tw}/corner.css +18 -12
  120. package/{dist/tw → tw}/elevation.css +23 -17
  121. package/{dist/tw → tw}/index.css +12 -10
  122. package/tw/index.d.ts +1 -0
  123. package/tw/intent.css +312 -0
  124. package/tw/modifiers.css +127 -0
  125. package/tw/native.css +320 -0
  126. package/tw/presentation.css +139 -0
  127. package/tw/reset.css +10 -0
  128. package/{dist/tw/reset.css → tw/reset.rules.css} +21 -22
  129. package/tw/size.css +34 -0
  130. package/tw/surface.css +9 -0
  131. package/tw/surface.rules.css +212 -0
  132. package/{dist/tw → tw}/theme.css +121 -45
  133. package/tw/typography.css +8 -0
  134. package/{dist/tw/typography.css → tw/typography.rules.css} +0 -3
  135. package/{dist/tw → tw}/utilities/content.css +212 -50
  136. package/tw/utilities/index.css +11 -0
  137. package/tw/utilities/layout.css +208 -0
  138. package/tw/utilities/rules.css +8 -0
  139. package/dist/tw/aesthetics/sketch.css +0 -333
  140. package/dist/tw/components/button.css +0 -139
  141. package/dist/tw/components/index.css +0 -36
  142. package/dist/tw/components/loader.css +0 -116
  143. package/dist/tw/components/surface.css +0 -175
  144. package/dist/tw/intent.css +0 -228
  145. package/dist/tw/native.css +0 -203
  146. package/dist/tw/palette.css +0 -460
  147. package/dist/tw/presentation.css +0 -68
  148. package/dist/tw/surface.css +0 -61
  149. package/dist/tw/utilities/index.css +0 -6
  150. package/dist/tw/utilities/layout.css +0 -130
  151. /package/{dist/tw → tw}/aesthetics/index.css +0 -0
@@ -0,0 +1,309 @@
1
+ ---
2
+ title: Temas
3
+ description: Modo claro e escuro, como trocar a paleta pelas cores da marca, como definir uma intenção própria, e cada token de cor, de intenção, fundamental e de fonte com o seu padrão.
4
+ order: 5
5
+ source: faefe01e9a435bd2630c846cc365f3c8783107df
6
+ ---
7
+
8
+ # Temas
9
+
10
+ A tela de configurações funciona e tem a cara dos padrões do pacote: ações quase pretas numa página quase branca. Esta página a deixa com a sua cara. Ela trata do modo claro e escuro, depois troca a cor primária por uma cor da marca nos dois modos e, por fim, define uma intenção que o pacote não entrega. A segunda metade é a referência de consulta: cada token de cor, de intenção, fundamental e de fonte, com o seu padrão.
11
+
12
+ ## Claro e escuro
13
+
14
+ De fábrica, a página segue o sistema operacional: clara quando o sistema do usuário está no claro, escura quando está no escuro. Você não precisa fazer nada para isso.
15
+
16
+ Para deixar o usuário escolher, coloque um seletor de tema no elemento raiz:
17
+
18
+ ```html
19
+ <html data-theme="dark">
20
+ …
21
+ </html>
22
+ ```
23
+
24
+ | Tema | Seletores equivalentes |
25
+ | ------ | ------------------------------------------------ |
26
+ | Claro | `.light`, `.theme-light`, `[data-theme="light"]` |
27
+ | Escuro | `.dark`, `.theme-dark`, `[data-theme="dark"]` |
28
+
29
+ Uma tela de configurações com a escolha "Sistema / Claro / Escuro" remove o atributo para Sistema e o define para as outras duas opções.
30
+
31
+ Como isso é resolvido:
32
+
33
+ - Um seletor de tema define a propriedade CSS `color-scheme` e a cor do texto do elemento como `--color-text`. Cada token de cor guarda o seu valor claro e o seu valor escuro ao mesmo tempo, por meio de `light-dark()`, e o `color-scheme` do elemento escolhe um deles.
34
+ - `color-scheme` é herdado, então um seletor aplica o tema a tudo o que está dentro dele. Um seletor em qualquer elemento aplica o tema àquela parte da página: uma barra lateral escura numa página clara é `<aside class="dark">`, e o texto dentro dela recebe a cor de texto do tema escuro.
35
+ - Um seletor não define fundo. Dê você mesmo o fundo da região, como `background: var(--color-background)`. Qualquer classe utilitária ou de componente no mesmo elemento substitui a cor de texto do seletor.
36
+ - O seletor mais próximo vence, em qualquer profundidade. Um card `.light` dentro de uma página `.dark` é claro.
37
+ - Sem seletor, a raiz tem `color-scheme: light dark`, que segue o sistema.
38
+ - Coloque um único tema por elemento. Se um elemento tiver um seletor claro e um escuro, o escuro vence, mas não conte com isso.
39
+ - Definir você mesmo o `color-scheme` num elemento aplica o tema aos tokens do mesmo jeito, porque ele é a única coisa que a paleta lê. Isso também aplica o tema a partes nativas, como barras de rolagem e o interior de controles de formulário. O texto simples dentro dele mantém a cor que herdou até você definir também `color: var(--color-text)`.
40
+
41
+ Toda cor de componente vem de um token ou de `currentColor`, então os componentes seguem o tema sem regras próprias de modo escuro. As marcas que o pacote desenha, como o visto do checkbox e a seta do select, também usam `currentColor`. Ícones e imagens que você adiciona ficam por sua conta.
42
+
43
+ `light-dark()` funciona a partir do Chrome 123, Safari 17.5 e Firefox 120. O pacote como um todo exige Firefox 128; veja [Configuração → Requisitos](../setup.md#requisitos).
44
+
45
+ ### Impressão
46
+
47
+ Uma página é impressa no tema claro, seja qual for o tema que ela mostra na tela. Dentro de `@media print`, a raiz e todo seletor escuro definem `color-scheme: light`, então todo token é resolvido para o seu valor claro, inclusive o de uma barra lateral forçada para o escuro. O papel é claro, e texto escuro sobre ele gasta menos tinta do que uma página escura impressa.
48
+
49
+ Componentes preenchidos imprimem o seu fundo. Por padrão, o navegador tira os fundos de uma página impressa, o que deixa o texto de contraste de um botão sólido sobre o nada, então todo componente define `print-color-adjust: exact`. A propriedade é herdada, de modo que o conteúdo de um componente também mantém as suas cores.
50
+
51
+ Um limite: um utilitário `dark:` continua valendo na impressão. Ele casa pelo seletor, não pelo `color-scheme`, então com `<html class="dark">` e `dark:bg-black` num elemento, esse fundo sai preto no papel. Escreva um utilitário `print:` ao lado dele se a página impressa importar.
52
+
53
+ ### A variante `dark:`
54
+
55
+ Com os entrypoints de código-fonte do Tailwind (`/tw`), o pacote substitui a variante `dark:` do Tailwind para que os seus próprios utilitários sigam o mesmo tema que os tokens. Um utilitário `dark:` se aplica sob um seletor escuro explícito no elemento ou num ancestral, ou sob uma preferência de sistema escura quando nenhum ancestral define um tema:
56
+
57
+ ```html
58
+ <html>
59
+ <body>
60
+ <p class="dark:text-white">Follows the system preference</p>
61
+ <div class="light">
62
+ <p class="dark:text-white">Stays light: this part of the page chose a theme</p>
63
+ </div>
64
+ </body>
65
+ </html>
66
+ ```
67
+
68
+ Ela difere dos tokens em um caso: um tema explícito aninhado dentro do tema oposto. Um elemento `.light` dentro de um `.dark` tem tokens claros, porque o `color-scheme` mais próximo vence. Mas `dark:` casa por seletor, e `.dark *` casa com todo elemento dentro de `.dark`, então um utilitário `dark:` dentro daquele elemento `.light` ainda se aplica. Se uma página usa tanto tokens quanto utilitários `dark:`, não aninhe temas opostos.
69
+
70
+ Os entrypoints compilados não definem uma variante `dark:`; eles não têm um build do Tailwind em que defini-la.
71
+
72
+ ## Mude a cor da marca
73
+
74
+ A cor primária é quase preta numa página clara e quase branca numa escura. Para transformá-la numa cor da marca, substitua a família primária inteira: a cor base e as suas quatro companheiras. Cada uma guarda um valor claro e um escuro:
75
+
76
+ ```css
77
+ :root {
78
+ --color-primary: light-dark(#0f766e, #2dd4bf);
79
+ --color-primary-contrast: light-dark(#ffffff, #042f2e);
80
+ --color-primary-hover: light-dark(#115e59, #5eead4);
81
+ --color-primary-subtle: light-dark(#ccfbf1, #134e4a);
82
+ --color-primary-strong: light-dark(#115e59, #5eead4);
83
+ }
84
+ ```
85
+
86
+ Para que serve cada uma:
87
+
88
+ | Token | Papel | Verificação |
89
+ | -------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------- |
90
+ | `--color-primary` | O preenchimento de um botão primário sólido, de um toggle marcado, de uma barra de progresso. | Texto em `-contrast` sobre ela chega a 4.5:1. |
91
+ | `--color-primary-contrast` | Texto e ícones sobre um preenchimento primário total. | Veja acima. |
92
+ | `--color-primary-hover` | O preenchimento sob o ponteiro. | Texto em `-contrast` sobre ela ainda chega a 4.5:1. |
93
+ | `--color-primary-subtle` | O tom claro por trás dos componentes soft. | Texto em `-strong` sobre ela chega a 4.5:1. |
94
+ | `--color-primary-strong` | Texto, ícones e bordas onde o preenchimento não é total: soft e ghost. | Chega a 4.5:1 sobre a página e sobre `-subtle`. |
95
+
96
+ Os valores em verde-azulado acima medem, no modo claro e no escuro: 5.47:1 e 7.77:1 para o preenchimento e o seu texto, 7.27:1 e 13.38:1 para o tom forte sobre a página, e 6.73:1 e 6.41:1 para o tom forte sobre o tom suave.
97
+
98
+ Substitua a família inteira. Mudar só `--color-primary` deixa as companheiras no antigo quase preto, então um badge primário soft mantém o texto cinza e um botão com hover pisca em preto. O anel de foco é desenhado a partir de `--color-primary` com 64% de opacidade, então ele acompanha a cor da marca sem precisar de mudança própria.
99
+
100
+ O mesmo padrão funciona para todas as famílias em [Tokens de cor](#tokens-de-cor): `--color-accent` é o que `.secondary` lê, e as quatro famílias de status são `success`, `warning`, `destructive` e `info`. Defina-as no `:root` para a página inteira, ou em qualquer elemento para mudar o tema só do que está dentro dele.
101
+
102
+ Os valores precisam ser cores completas: hex, `rgb()`, `oklch()` ou uma variável que você mesmo declarou. Variáveis da paleta do Tailwind, como `--color-teal-700`, existem num build `/tw`, vindas do seu tema do Tailwind, mas o CSS compilado declara só as cores da paleta que o próprio pacote usa. Com CSS compilado, uma referência a qualquer outra variável da paleta fica vazia, e a cor que ela alimenta se perde.
103
+
104
+ Com `/tw`, você pode descartar os tons do Tailwind que o seu design não usa, para que `bg-red-500` e companhia deixem de ser classes. Mantenha os que o tema lê, `neutral`, `emerald`, `amber`, `rose`, `indigo` e `white`: apagados, as cores construídas a partir deles se perdem sem nenhum erro. [Tailwind CSS v4 → Descarte a paleta do Tailwind](../integrating/tailwind.md#descarte-a-paleta-do-tailwind) tem o bloco para copiar.
105
+
106
+ ## Sua própria intenção
107
+
108
+ O pacote entrega seis intenções, `.primary`, `.secondary`, `.success`, `.warning`, `.destructive` e `.info`, mais o padrão, `.neutral`. Para adicionar uma, como uma cor "Beta" para funcionalidades em prévia, escreva uma classe que define os sete slots de intenção. Use cores completas, com `light-dark()` para tudo o que muda entre os temas:
109
+
110
+ ```css
111
+ .beta {
112
+ --intent-color: #7c3aed;
113
+ --intent-contrast: #ffffff;
114
+ --intent-hover: #6d28d9;
115
+ --intent-strong: light-dark(#5b21b6, #c4b5fd);
116
+ --intent-subtle: light-dark(#ede9fe, #4c1d95);
117
+ --intent-border: light-dark(#7c3aed, #a78bfa);
118
+ --intent-fill-max: 100%;
119
+ }
120
+ ```
121
+
122
+ ```html
123
+ <span class="badge beta">Beta</span> <button class="btn beta" type="button">Try the new editor</button>
124
+ ```
125
+
126
+ Esses valores medem 5.7:1 para branco sobre o preenchimento, 7.1:1 para branco sobre a cor de hover, 8.61:1 (claro) e 10.72:1 (escuro) para o tom forte sobre a página, e 7.57:1 e 5.93:1 para o tom forte sobre o tom suave.
127
+
128
+ **Defina todos os slots**, incluindo `--intent-fill-max`. Cada componente redefine os sete slots para os valores neutros na sua própria raiz, então um slot que você deixa de fora fica com o valor do neutro e, sem `--intent-fill-max: 100%`, a sua intenção só preenche até 20%, como o neutro. O que cada slot faz está em [Tokens de intenção](#tokens-de-intenção).
129
+
130
+ A classe funciona em tudo o que aceita intenção: botões, badges, campos e toggles, cards sólidos e ghost, barras de progresso, skeletons, balões de tooltip e o resto. Alguns comportamentos foram escritos para os seis nomes embutidos, e uma intenção personalizada não os recebe:
131
+
132
+ - **Um repouso discreto, sem tom.** Um `.card.soft`, um `.panel` e um `.alert` neutros ficam sobre o tom de fundo discreto, e só reconhecem uma intenção pelas seis classes embutidas. `.card.soft.beta`, `.panel.beta` e `.alert.beta` são desenhados como o neutro: o tom de fundo discreto em vez de um tom violeta. A sua intenção ainda colore o texto e a borda deles.
133
+ - **O tom dos chips.** Uma tecla `.kbd` ou um bloco de código `.beta` mostra o seu tom `--intent-subtle`, mas não os 12% extras de `--intent-color` que uma intenção embutida acrescenta por cima.
134
+ - **Classes solo.** Uma [classe solo](./solo.md) como `.neobrutalism-solo` só aceita intenção das seis classes embutidas, então `.neobrutalism-solo.beta` é desenhado como neutro.
135
+ - **O texto do hint.** Um [`.hint`](./forms.md#mostre-um-erro-de-validação) só aparece no tom legível de uma intenção com as seis classes embutidas, então `.hint.beta` continua na cor secundária.
136
+ - **Linhas de tabela.** Uma linha do corpo muda a cor do texto, da linha divisória e do hover só com as classes de intenção embutidas. `<tr class="beta">` fica igual ao resto da sua tabela.
137
+
138
+ Se você precisa disso, há dois caminhos:
139
+
140
+ - **Mude o tema de uma intenção embutida.** Defina a família `--color-info` (ou outra) com as suas cores, como em [Mude a cor da marca](#mude-a-cor-da-marca), e escreva `.info`. Tudo, incluindo os casos acima, passa a funcionar. O custo é que a mudança alcança todo `.info` dentro do elemento em que você a definiu, então defina-a no elemento mais restrito que funcione, e não faça isso com uma intenção que a página já usa com outro significado.
141
+ - **Pinte você mesmo.** Escreva o seu próprio CSS para aquele componente, como um `background-color` em `.panel.beta`.
142
+
143
+ > **A intenção não é herdada.** Cada componente redefine os slots de intenção na sua própria raiz, então um contêiner `.success` não recolore um botão destrutivo dentro dele. Coloque a classe de intenção no elemento que mostra a cor.
144
+
145
+ ## Tokens de cor
146
+
147
+ Cada token de cor guarda um valor claro e um escuro por meio de `light-dark()`; um único valor significa que os dois temas o usam. Nomes de paleta como `neutral-950` são da paleta padrão do Tailwind, que o CSS compilado do pacote declara para as cores que usa.
148
+
149
+ Cada linha é um ponto de sobrescrita: defina-a no `:root` para mudar o tema da página, ou em qualquer elemento para mudar o tema do que está dentro dele. As linhas `-hover`, `-subtle`, `-strong` e `-contrast` são companheiras da cor base da sua família e não a acompanham, então mude o tema da família inteira. A família `text` não tem linha `-subtle`: a intenção neutra pega o seu tom suave de `--color-surface`.
150
+
151
+ | Token | Claro, escuro | Finalidade |
152
+ | ------------------------------ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------- |
153
+ | `--color-primary` | `neutral-950`, `neutral-50` | Preenchimento de `.primary`. |
154
+ | `--color-primary-contrast` | `neutral-50`, `neutral-950` | Texto e ícones sobre um preenchimento primário total. |
155
+ | `--color-primary-hover` | `neutral-700`, `neutral-200` | Preenchimento primário sob o ponteiro. |
156
+ | `--color-primary-subtle` | `neutral-200`, `neutral-900` | Tom primário por trás dos componentes soft. |
157
+ | `--color-primary-strong` | `neutral-900`, `neutral-100` | Texto, ícones e bordas primários onde o preenchimento não é total. |
158
+ | `--color-accent` | `neutral-600`, `neutral-400` | Preenchimento de `.secondary`. |
159
+ | `--color-accent-contrast` | `neutral-50`, `neutral-950` | Texto e ícones sobre um preenchimento secundário total. |
160
+ | `--color-accent-hover` | `neutral-700`, `neutral-300` | Preenchimento secundário sob o ponteiro. |
161
+ | `--color-accent-subtle` | `neutral-100`, `neutral-800` | Tom secundário por trás dos componentes soft. |
162
+ | `--color-accent-strong` | `neutral-800`, `neutral-200` | Texto, ícones e bordas secundários onde o preenchimento não é total. |
163
+ | `--color-border` | `neutral-400`, `neutral-700` | Borda de superfícies neutras, tabelas, divisores e teclas. |
164
+ | `--color-border-hover` | `neutral-600`, `neutral-500` | Borda sob o ponteiro. |
165
+ | `--color-control-border` | `neutral-500` | Borda em repouso de controles de texto e toggles neutros, desenhada com uma fração da força nos controles de texto. |
166
+ | `--color-background` | `neutral-50`, `neutral-950` | A página. |
167
+ | `--color-foreground` | `neutral-100`, `neutral-900` | O tom de fundo discreto um passo distante da página: cards soft, painéis e alertas neutros. |
168
+ | `--color-surface` | `neutral-200`, `neutral-800` | Mais um passo: superfícies aninhadas e esmaecidas, e o tom da intenção neutra. |
169
+ | `--color-text` | `neutral-950`, `neutral-50` | Texto do corpo, e a cor da intenção neutra. |
170
+ | `--color-text-secondary` | `neutral-700`, `neutral-400` | Texto secundário, como o `.hint`. |
171
+ | `--color-text-contrast` | `neutral-50`, `neutral-950` | Texto sobre um preenchimento total de `--color-text`, como a marca de um toggle neutro marcado. |
172
+ | `--color-text-hover` | `neutral-700`, `neutral-200` | Cor neutra sob o ponteiro. |
173
+ | `--color-text-strong` | `neutral-900`, `neutral-100` | Texto, ícones e bordas neutros onde o preenchimento não é total. |
174
+ | `--color-tooltip` | `white`, `neutral-700` | Fundo de um balão de tooltip sem intenção. Escolhido por tema para parecer elevado nos dois. |
175
+ | `--color-tooltip-contrast` | `neutral-900`, `neutral-100` | Texto sobre `--color-tooltip`. |
176
+ | `--color-success` | `emerald-700` | Preenchimento de `.success`. |
177
+ | `--color-success-contrast` | `neutral-50` | Texto sobre um preenchimento de sucesso total: 5.14:1. |
178
+ | `--color-success-hover` | `#007552`, `#008e66` | Preenchimento de sucesso sob o ponteiro. |
179
+ | `--color-success-subtle` | `emerald-100`, `emerald-900` | Tom de sucesso por trás dos componentes soft. |
180
+ | `--color-success-strong` | `emerald-800`, `emerald-300` | Texto, ícones e bordas de sucesso onde o preenchimento não é total. |
181
+ | `--color-warning` | `amber-600` | Preenchimento de `.warning`. |
182
+ | `--color-warning-contrast` | `neutral-950` | Texto sobre um preenchimento de aviso total: quase preto, não a cor da página. 6.19:1. |
183
+ | `--color-warning-hover` | `#d46700`, `#e78300` | Preenchimento de aviso sob o ponteiro. |
184
+ | `--color-warning-subtle` | `amber-100`, `amber-900` | Tom de aviso por trás dos componentes soft. |
185
+ | `--color-warning-strong` | `amber-800`, `amber-300` | Texto, ícones e bordas de aviso onde o preenchimento não é total. |
186
+ | `--color-destructive` | `rose-700` | Preenchimento de `.destructive`. |
187
+ | `--color-destructive-contrast` | `neutral-50` | Texto sobre um preenchimento destrutivo total: 5.78:1. |
188
+ | `--color-destructive-hover` | `#c00036`, `#d1054b` | Preenchimento destrutivo sob o ponteiro. |
189
+ | `--color-destructive-subtle` | `rose-100`, `rose-900` | Tom destrutivo por trás dos componentes soft. |
190
+ | `--color-destructive-strong` | `rose-800`, `rose-300` | Texto, ícones e bordas destrutivos onde o preenchimento não é total. |
191
+ | `--color-info` | `indigo-600` | Preenchimento de `.info`. |
192
+ | `--color-info-contrast` | `neutral-50` | Texto sobre um preenchimento informativo total: 6.19:1. |
193
+ | `--color-info-hover` | `#4b36e9`, `#5e4ff9` | Preenchimento informativo sob o ponteiro. |
194
+ | `--color-info-subtle` | `indigo-100`, `indigo-900` | Tom informativo por trás dos componentes soft. |
195
+ | `--color-info-strong` | `indigo-800`, `indigo-300` | Texto, ícones e bordas informativos onde o preenchimento não é total. |
196
+
197
+ Mudanças de tema pertencem a esses valores, não a regras de componente que verificam o tema.
198
+
199
+ ## Tokens de intenção
200
+
201
+ Uma classe de intenção define estes sete slots, e os componentes os leem. Como todo componente lê os mesmos sete nomes, uma classe que define os sete funciona como intenção, como mostra [Sua própria intenção](#sua-própria-intenção).
202
+
203
+ | Token | Finalidade |
204
+ | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
205
+ | `--intent-color` | A cor base da intenção, aquilo de que um preenchimento é feito. |
206
+ | `--intent-contrast` | Texto sobre um preenchimento total de `--intent-color`. |
207
+ | `--intent-hover` | A cor base sob o ponteiro. |
208
+ | `--intent-strong` | A intenção como texto, ícone ou borda sempre que o preenchimento não é total. |
209
+ | `--intent-subtle` | O tom claro por trás dos componentes soft e dos trilhos de progresso. O neutro usa `--color-surface`. |
210
+ | `--intent-border` | Cor das linhas. Sem intenção, é o `--ui-ink` da estética e, depois, `--color-border`; controles de texto e toggles leem `--ui-control-ink`, depois `--ui-ink` e depois `--color-control-border`, e as tabelas leem `--ui-rule-ink` primeiro. |
211
+ | `--intent-fill-max` | Até onde um preenchimento dessa intenção pode ir. `100%` para toda intenção, exceto a neutra. |
212
+
213
+ `--intent-color` e `--intent-strong` não são intercambiáveis. A cor base é escolhida para preencher; o tom forte é escolhido para ser lido sobre a página. Um componente soft ou ghost imprime o tom forte, e é por isso que um aviso soft aparece em amber-800 enquanto um sólido é preenchido com amber-600.
214
+
215
+ O tom forte também precisa continuar reconhecível como o seu próprio matiz. Numa página escura, a tonalidade `-100` de cada família é um tom pálido quase sem cor em tamanhos pequenos: um badge de sucesso soft e um destrutivo soft pareceriam ambos brancos. Por isso, os tons fortes do escuro são `-300`, e os tons por baixo deles são `-900`, que medem 5.0:1 ou mais onde quer que um preenchimento parcial tenha texto, e mais de 9:1 sobre a página.
216
+
217
+ `--intent-border` existe para que uma borda neutra continue no cinza discreto de borda, e não na cor do texto. Tudo o que desenha uma linha o lê: bordas de controles, linhas divisórias de tabelas, divisores, teclas e barras de citação.
218
+
219
+ `--intent-fill-max` existe para a intenção neutra, cuja cor é a própria cor do texto da página. Todas as outras intenções são um matiz, legível como um tom pálido a 12% e saturado a 100%; um cinza preenchido a 100% é um bloco preto ou branco, o elemento que mais chama atenção na página justamente para a intenção que não significa nada em particular. O neutro para em `20%`, então `.solid` dá a ele um cinza discreto que ainda fica um passo além do `.soft`. O hover soma o seu passo por cima do teto, então um preenchimento limitado ainda fica mais intenso sob o ponteiro.
220
+
221
+ A cor do texto acompanha o preenchimento. `--intent-contrast` é a cor do texto para um preenchimento total; impressa sobre um quinto de preenchimento, seria branco sobre cinza-claro. Por isso, o texto de contraste só aparece depois que o preenchimento passa da metade, e chega à força total com o preenchimento total; abaixo disso, o componente imprime `--intent-strong`. Um neutro limitado, portanto, imprime o tom forte. Um estado que levanta o teto de propósito, como um checkbox marcado, chega ao preenchimento total e imprime a cor de contraste.
222
+
223
+ ## Tokens fundamentais
224
+
225
+ Os tokens fundamentais definem layout, formato, movimento, foco, profundidade e empilhamento. Sobrescreva-os no `:root`, ou num elemento para o que está dentro dele.
226
+
227
+ As quatro sombras `--elevation-*` são para elementos que você mesmo estiliza. Elas são separadas das classes `.flat`, `.raised` e `.floating`, que escalam a sombra do próprio componente e não desenham nada até que uma estética ou uma dessas classes peça profundidade; veja [Composição → Elevação](./composing.md#elevação). Ambas usam os pesos nenhum, pequeno, médio e grande, mas uma é um valor fixo e a outra escala partes da sombra, então elas nem sempre têm a mesma aparência.
228
+
229
+ | Token | Padrão | Finalidade |
230
+ | -------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
231
+ | `--font-default` | `"Segoe UI", system-ui, sans-serif` | Fonte da página. Veja [Fontes](#fontes). |
232
+ | `--container-narrow` | `48rem` | Largura de `.section-content.narrow`. |
233
+ | `--container-max` | `80rem` | Largura de `.section-content`. |
234
+ | `--container-wide` | `90rem` | Largura de `.section-content.wide`. |
235
+ | `--layout-gutter` | `clamp(1rem, 4vw, 2rem)` | Padding lateral de `.section`, que cresce com a janela. |
236
+ | `--layout-section-block` | `clamp(4rem, 9vw, 7rem)` | Padding superior e inferior de `.section`, que cresce com a janela. |
237
+ | `--layout-gap` | `1rem` | Espaçamento de `.view`, `.stack`, `.cluster` e `.auto-grid`. |
238
+ | `--layout-grid-min` | `16rem` | Coluna mais estreita de `.auto-grid`. |
239
+ | `--radius-small` | `0.25rem` | Canto de chips pequenos: `.kbd` e `.code`. |
240
+ | `--radius-control` | `0.5rem` | Canto de botões, campos e balões de tooltip. |
241
+ | `--radius-surface` | `0.875rem` | Canto de cards, painéis e alertas. |
242
+ | `--control-height` | `2.5rem` | Altura mínima de um botão padrão e de um controle de texto. |
243
+ | `--border-width` | `1px` | Espessura da borda. |
244
+ | `--elevation-color` | `rgb(15 23 42 / 0.08)` no claro, `rgb(0 0 0 / 0.55)` no escuro | A cor de sombra que as quatro elevações usam. Mais forte numa página escura, onde uma sombra leve não apareceria. |
245
+ | `--elevation-none` | `none` | Sem sombra. |
246
+ | `--elevation-sm` | `0 1px 2px`, `0 1px 3px` | Uma sombra leve para as suas próprias superfícies, como um card. |
247
+ | `--elevation-md` | `0 4px 6px -1px`, `0 2px 4px -2px` | Uma sombra para os seus próprios elementos elevados, como um menu dropdown. |
248
+ | `--elevation-lg` | `0 20px 25px -5px`, `0 8px 10px -6px` | Uma sombra para as suas próprias sobreposições, como um dialog modal. |
249
+ | `--focus-ring` | Não definido | Cor do anel de foco do teclado. Quando não está definido, `--color-primary` com 64% de opacidade, no elemento focado. |
250
+ | `--focus-ring-offset` | Não definido | Distância entre o anel e o elemento. Quando não está definido, o anel fica sobre a borda do elemento em qualquer estética. |
251
+ | `--focus-ring-width` | `3px` | Espessura do anel de foco do teclado. |
252
+ | `--motion-duration-fast` | `120ms` | O hover de uma linha de tabela. |
253
+ | `--motion-duration-normal` | `200ms` | Transições de cor, borda, sombra e clique, marcas de toggles e o balão de tooltip. |
254
+ | `--motion-duration-slow` | `400ms` | Mudanças de valor de progresso, e a base do ciclo de brilho do skeleton e do progresso. |
255
+ | `--motion-ease` | `cubic-bezier(0.2, 0, 0, 1)` | Easing de todas as transições. |
256
+ | `--z-popover` | `40` | Ordem de empilhamento dos balões de tooltip. Use nos seus próprios popovers para que eles empilhem do mesmo jeito. |
257
+ | `--breakpoint-xs` | `30rem` | O breakpoint responsivo `xs:`. Só num build `/tw`; os entrypoints compilados não o declaram. |
258
+
259
+ Cada sombra `--elevation-*` é composta das partes listadas, cada uma em `--elevation-color`. As quatro sombras são compostas uma única vez, na raiz, então um `--elevation-color` que você define num contêiner não chega até elas: defina-o em `:root`, ou defina o próprio token `--elevation-*` no contêiner. As classes de elevação, como `.card.raised`, leem `--elevation-color` no elemento e seguem o valor de um contêiner, com uma exceção: toda classe de estética define o seu próprio `--elevation-color` na sua região. Um valor definido acima de uma região `.glass` ou `.pixel` não chega dentro dela. Defina-o no próprio elemento da estética, onde o seu utilitário ou CSS sem camada vence a classe, ou num elemento dentro da região. No glass, a sombra de uma superfície é montada no elemento `.glass`, então só um valor definido ali a muda. No `.neobrutalism` a sombra é desenhada na intenção ou na tinta, e o `.cyber` não desenha profundidade, então nenhum dos dois lê o token. O passo de hover que intensifica um preenchimento sob o ponteiro é um token de apresentação, `--hover-step`; veja [Personalização](./customizing.md#tokens-de-apresentação).
260
+
261
+ ## Fontes
262
+
263
+ O pacote não entrega arquivos de fonte e não faz requisições de rede. Cada token de fonte nomeia fontes já instaladas no dispositivo de quem lê, até você fornecer as suas.
264
+
265
+ | Token | Lido por | Sem o seu valor |
266
+ | ---------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
267
+ | `--font-default` | O reset, em `html` e `body`, e as regiões `.glass` e `.neobrutalism`. Os controles o herdam. | `"Segoe UI", system-ui, sans-serif` |
268
+ | `--font-mono` | Os utilitários de conteúdo `kbd`, `code` e `pre`, e `<kbd>`, `<code>` e `<pre>` com `/native` | `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`. Com `/tw`, o valor do seu tema do Tailwind. |
269
+ | `--font-pixel` | [`.pixel`](./aesthetics.md#pixel) e `.pixel-solo` | Não declarado. Cai numa pilha monoespaçada. |
270
+ | `--font-rounded` | [`.chunky-tile`](./aesthetics.md#chunky-tile) e `.chunky-tile-solo` | Não declarado. Cai em `--font-default` e, depois, numa pilha sans-serif. |
271
+ | `--font-cyber` | [`.cyber`](./aesthetics.md#cyber) e `.cyber-solo` | Não declarado. Cai numa pilha monoespaçada. |
272
+ | `--font-sketch` | [`.sketch`](./aesthetics.md#sketch) e `.sketch-solo` | Não declarado. Cai na família `cursive` da plataforma. |
273
+
274
+ `--font-default` só chega à página pelo reset, que `@codenhub/styles`, `/native`, `/tw`, `/tw/native` e `/tw/reset` incluem. Usando só `/theme` ou `/components`, defina você mesmo o `font-family` no `body` e defina `--font-default` com a mesma fonte: as regiões `.glass` e `.neobrutalism` definem o próprio `font-family` a partir do token, então uma fonte definida só no `body` não chega dentro delas. Ou defina só o token e escreva `font-family: var(--font-default)` no `body`. Os tokens das estéticas são lidos pela classe da própria estética, então funcionam com qualquer entrypoint.
275
+
276
+ Para usar uma web font, carregue-a como você carrega qualquer fonte e depois nomeie-a no token. Defina o token no `:root` para a página inteira, ou em qualquer elemento para aquela parte dela:
277
+
278
+ ```html
279
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
280
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
281
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400..700&display=swap" />
282
+ ```
283
+
284
+ ```css
285
+ :root {
286
+ --font-default: "Inter", system-ui, sans-serif;
287
+ }
288
+ ```
289
+
290
+ Uma fonte hospedada por você é declarada com `@font-face` e nomeada do mesmo jeito:
291
+
292
+ ```css
293
+ @font-face {
294
+ font-family: "Pixelify Sans";
295
+ src: url("/fonts/pixelify-sans.woff2") format("woff2");
296
+ font-weight: 400 700;
297
+ font-display: swap;
298
+ }
299
+
300
+ :root {
301
+ --font-pixel: "Pixelify Sans", monospace;
302
+ }
303
+ ```
304
+
305
+ Carregue os pesos de 400 a 700, e 800 para `--font-rounded`: os componentes definem `font-weight` de 400 a 700, e `.chunky-tile` usa 800 nos rótulos. Um navegador que não tem um peso o simula engrossando o regular, o que borra uma fonte pixelada ou manuscrita. Sempre termine a pilha com uma família genérica, como `sans-serif` ou `monospace`, para que o texto continue renderizando enquanto a fonte carrega ou se ela falhar.
306
+
307
+ ## A seguir
308
+
309
+ A tela tem as suas cores nos dois temas. [Estéticas](./aesthetics.md) muda do que ela é feita: contornos pretos grossos, vidro fosco, pixels e muito mais.
@@ -0,0 +1,127 @@
1
+ ---
2
+ title: Tooltips
3
+ description: Ajuda de campo que abre no hover e no foco, como ligá-la a leitores de tela e à tecla Escape, e onde um tooltip é cortado.
4
+ order: 4
5
+ source: ea0dd81935063e3e02f0b4d84e51fafab0511cc3
6
+ ---
7
+
8
+ # Tooltips
9
+
10
+ O switch "Public profile" da tela de configurações merece uma explicação curta: o que fica visível quando ele está ligado. Esta página acrescenta um botão de ajuda ao lado dele que mostra um tooltip no hover e no foco pelo teclado. O CSS mostra, esconde e desenha a mensagem; você a liga ao gatilho para os leitores de tela, adiciona a tecla Escape e confere se nada em volta a corta.
11
+
12
+ ## Um tooltip de ajuda
13
+
14
+ ```html
15
+ <div class="cluster tight">
16
+ <label class="cluster tight">
17
+ <input class="switch primary" type="checkbox" role="switch" name="public-profile" />
18
+ Public profile
19
+ </label>
20
+ <span class="tooltip">
21
+ <button class="tooltip-icon" type="button" aria-label="About public profiles" aria-describedby="public-profile-help">?</button>
22
+ <span class="tooltip-bubble" role="tooltip" id="public-profile-help">Anyone with the link can see your name, photo, and public projects.</span>
23
+ </span>
24
+ </div>
25
+ ```
26
+
27
+ As três partes:
28
+
29
+ - `.tooltip` envolve o gatilho e a mensagem. Ele posiciona a mensagem e não pinta nada.
30
+ - `.tooltip-bubble` é a mensagem. É um elemento de verdade, então pode ter um `id` para o qual o gatilho aponta.
31
+ - `.tooltip-icon` é um gatilho pequeno e redondo, para uma mensagem sem mais nada a que se prender. Qualquer elemento focável pode ser o gatilho no lugar dele: envolva um `.btn` existente em `.tooltip` e ele mantém o próprio visual.
32
+
33
+ Faça a ligação você mesmo: um `id` no balão, `aria-describedby` no gatilho apontando para esse `id` e `role="tooltip"` no balão. Assim, um leitor de tela lê a mensagem como a descrição do gatilho. O CSS não consegue fazer essa ligação e, sem ela, a mensagem é só visual.
34
+
35
+ O gatilho precisa ser focável, como um `<button>`, para que quem usa teclado alcance a mensagem. O balão abre quando qualquer coisa dentro de `.tooltip` tem foco, então ele também abre depois de um clique do mouse no gatilho.
36
+
37
+ ## Posicionamento
38
+
39
+ O balão abre acima do gatilho, centralizado na horizontal, com um espaçamento de 0.5rem. Defina `data-tooltip-position` no `.tooltip` para escolher outro lado:
40
+
41
+ ```html
42
+ <span class="tooltip" data-tooltip-position="bottom">
43
+ <button class="btn ghost sm" type="button" aria-describedby="renewal-help">Renews 12 March 2027</button>
44
+ <span class="tooltip-bubble" role="tooltip" id="renewal-help">Your card is charged on this date.</span>
45
+ </span>
46
+ ```
47
+
48
+ | `data-tooltip-position` | Balão |
49
+ | ----------------------- | ------------------------------------------------ |
50
+ | _nenhum_ ou `"top"` | Acima do gatilho, centralizado. |
51
+ | `"bottom"` | Abaixo do gatilho, centralizado. |
52
+ | `"left"` | À esquerda do gatilho, centralizado na vertical. |
53
+ | `"right"` | À direita do gatilho, centralizado na vertical. |
54
+
55
+ Um balão tem a largura do texto, até 18rem, e a partir daí quebra a linha.
56
+
57
+ ### Onde um tooltip é cortado
58
+
59
+ O balão é posicionado só com CSS, no lado que você escolheu. Nada mede a página: ele não se move para ficar dentro da janela, não vira para o outro lado quando falta espaço e não vai para a camada superior (top layer) da página. Isso tem três consequências:
60
+
61
+ - **Um contêiner com rolagem ou recorte o corta.** Um ancestral com `overflow: hidden`, `auto` ou `scroll` recorta o balão na borda dele. A tabela de chaves de API da tela de configurações fica num `.table-wrap`, que tem rolagem, então um tooltip acima da primeira linha é cortado no topo do wrapper. Aumentar o `z-index` não ajuda: ele muda sobre o que o balão é pintado, não se o contêiner o recorta.
62
+ - **A borda da janela o corta.** Um tooltip acima da primeira linha de uma página, ou um tooltip à direita perto da borda direita, sai da tela.
63
+ - **Esquerda e direita são lados físicos.** Numa página da direita para a esquerda, `"left"` continua significando o lado esquerdo da tela.
64
+
65
+ O que fazer:
66
+
67
+ - Escolha um lado com espaço: na primeira linha de uma tabela, use `data-tooltip-position="bottom"`.
68
+ - Tire o gatilho do tooltip de dentro do contêiner que recorta, ou remova o `overflow` de um contêiner que não precisa dele.
69
+ - Se a posição do gatilho não puder ser conhecida de antemão, como numa lista com rolagem ou num painel redimensionável, use uma biblioteca de posicionamento ou o componente de popover do seu framework, que consegue medir e virar. Você ainda pode dar ao elemento da mensagem as classes de `.tooltip-bubble` para o visual, mas mostrar, esconder e posicionar, como descrito nesta página, passam a ser trabalho dessa biblioteca, e não do `.tooltip`.
70
+
71
+ ## Hover, permanência e Escape
72
+
73
+ O WCAG 1.4.13 pede três coisas de um conteúdo que aparece no hover ou no foco. O pacote resolve duas:
74
+
75
+ - **Sobrevoável (hoverable).** Quando o ponteiro sai do gatilho, o balão continua visível por `--tooltip-linger` (300ms) e depois desaparece aos poucos, para que o ponteiro consiga atravessar o espaço até ele. Ele continua aberto enquanto o ponteiro estiver em cima dele. Um balão fechado fica com `visibility: hidden`, então ele nunca captura o ponteiro.
76
+ - **Persistente.** Ele continua aberto até o ponteiro e o foco saírem.
77
+ - **Dispensável.** O usuário precisa conseguir fechá-lo sem mover o ponteiro nem o foco, normalmente com Escape. O CSS não consegue escutar uma tecla, então essa parte é sua.
78
+
79
+ Para mudar o tempo de permanência, defina `--tooltip-linger` no elemento `.tooltip`, por exemplo `style="--tooltip-linger: 500ms"`. O wrapper declara o seu próprio padrão, então um valor definido num elemento pai do `.tooltip` não tem efeito. Deixe o tempo longo o bastante para o ponteiro alcançar o balão. Ela é uma das seis [variáveis públicas de componente](./customizing.md#variáveis-de-componente).
80
+
81
+ Para o Escape, escreva `data-state="closed"` no `.tooltip`: isso esconde o balão mesmo enquanto ele está com hover ou com foco. Remova o atributo só quando o ponteiro e o foco tiverem saído do tooltip, para que o próximo hover ou foco o abra de novo. Removê-lo antes, enquanto o gatilho ainda tem foco, faz a mensagem reaparecer sem que o usuário faça nada.
82
+
83
+ ```js
84
+ for (const tooltip of document.querySelectorAll(".tooltip")) {
85
+ let pointerInside = tooltip.matches(":hover");
86
+
87
+ tooltip.addEventListener("pointerenter", () => {
88
+ pointerInside = true;
89
+ });
90
+
91
+ tooltip.addEventListener("pointerleave", () => {
92
+ pointerInside = false;
93
+ if (!tooltip.contains(document.activeElement)) tooltip.removeAttribute("data-state");
94
+ });
95
+
96
+ tooltip.addEventListener("focusout", (event) => {
97
+ const focusStaysInside = tooltip.contains(event.relatedTarget);
98
+ if (!focusStaysInside && !pointerInside) tooltip.removeAttribute("data-state");
99
+ });
100
+ }
101
+
102
+ document.addEventListener("keydown", (event) => {
103
+ if (event.key !== "Escape") return;
104
+ for (const tooltip of document.querySelectorAll(".tooltip:hover, .tooltip:focus-within")) {
105
+ tooltip.dataset.state = "closed";
106
+ }
107
+ });
108
+ ```
109
+
110
+ `data-state="open"` faz o contrário: mostra o balão sem hover nem foco, para uma mensagem que deve ficar visível, ou para um teste ou uma captura de tela.
111
+
112
+ ## Como o balão aparece
113
+
114
+ Sem classe de intenção, o balão usa `--color-tooltip`, um fundo escolhido por tema: quase branco numa página clara, cinza médio numa escura, com `--color-tooltip-contrast` como cor do texto. Quase branco mede só 1.04:1 em relação a uma página clara, então o balão também desenha uma borda fina, e um `.edgeless` de um contêiner não consegue removê-la. Um `.edgeless` no próprio balão ainda consegue. O fundo continua opaco com qualquer apresentação, para que o balão continue legível sobre o que quer que ele cubra.
115
+
116
+ Uma classe de intenção preenche o balão com a cor dessa intenção e troca o texto para a cor de contraste correspondente:
117
+
118
+ - `.tooltip-bubble.primary` tem fundo quase preto com texto quase branco numa página clara, e fundo quase branco com texto quase preto numa escura.
119
+ - `.tooltip-bubble.destructive` tem fundo vermelho com texto claro nos dois temas.
120
+
121
+ Coloque as classes de intenção, apresentação, estética e elevação no `.tooltip-bubble`, o elemento que é pintado, e não no `.tooltip`. O balão é plano por padrão, mesmo numa estética que desenha profundidade; adicione `.raised` ou `.floating` ao balão para elevá-lo. Uma estética em vigor dá forma ao balão como a qualquer outro componente; com `.glass`, ele fica fosco como um card. O `.tooltip-icon` assume o canto da estética: quadrado com `.neobrutalism` e `.pixel`, um losango com `.cyber`.
122
+
123
+ O balão aparece sem o efeito de crescer quando o usuário pede movimento reduzido.
124
+
125
+ ## A seguir
126
+
127
+ A tela de configurações está completa no visual padrão. [Temas](./theming.md) dá a ela um modo escuro e as cores da sua marca.