@codenhub/styles 0.6.0 → 0.7.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 (113) hide show
  1. package/NOTICE +18 -16
  2. package/README.es.md +61 -0
  3. package/README.md +21 -16
  4. package/README.pt-BR.md +61 -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/components.css +2 -2
  13. package/dist/index.css +2 -2
  14. package/dist/native.css +2 -2
  15. package/dist/palette.css +1 -1
  16. package/dist/theme.css +2 -2
  17. package/dist/tw/aesthetics/chunky-tile.css +81 -23
  18. package/dist/tw/aesthetics/cyber.css +86 -29
  19. package/dist/tw/aesthetics/glass.css +177 -50
  20. package/dist/tw/aesthetics/neobrutalism.css +98 -22
  21. package/dist/tw/aesthetics/pixel.css +93 -8
  22. package/dist/tw/aesthetics/sketch.css +87 -22
  23. package/dist/tw/box.css +21 -2
  24. package/dist/tw/components/feedback.css +2 -2
  25. package/dist/tw/components/form.css +58 -19
  26. package/dist/tw/components/index.css +3 -4
  27. package/dist/tw/components/surface.css +15 -6
  28. package/dist/tw/index.css +1 -1
  29. package/dist/tw/intent.css +6 -5
  30. package/dist/tw/native.css +8 -8
  31. package/dist/tw/palette.css +6 -6
  32. package/dist/tw/reset.css +15 -15
  33. package/dist/tw/theme.css +29 -17
  34. package/dist/tw/utilities/content.css +43 -1
  35. package/dist/tw/utilities/layout.css +26 -12
  36. package/docs/accessibility.md +89 -60
  37. package/docs/changelog/0.1.1.md +1 -0
  38. package/docs/changelog/0.2.0.md +1 -0
  39. package/docs/changelog/0.3.0.md +1 -0
  40. package/docs/changelog/0.4.0.md +1 -0
  41. package/docs/changelog/0.5.0.md +8 -3
  42. package/docs/changelog/0.6.0.md +2 -1
  43. package/docs/changelog/0.7.0.md +50 -0
  44. package/docs/changelog/index.md +1 -0
  45. package/docs/concepts.md +188 -46
  46. package/docs/es/accessibility.md +150 -0
  47. package/docs/es/concepts.md +212 -0
  48. package/docs/es/index.md +104 -0
  49. package/docs/es/integrating/astro.md +35 -0
  50. package/docs/es/integrating/index.md +47 -0
  51. package/docs/es/integrating/nextjs.md +67 -0
  52. package/docs/es/integrating/svelte.md +45 -0
  53. package/docs/es/integrating/tailwind.md +78 -0
  54. package/docs/es/integrating/vue.md +31 -0
  55. package/docs/es/integrating/without-a-bundler.md +115 -0
  56. package/docs/es/setup.md +180 -0
  57. package/docs/es/usage/aesthetics.md +276 -0
  58. package/docs/es/usage/buttons.md +131 -0
  59. package/docs/es/usage/composing.md +164 -0
  60. package/docs/es/usage/content-and-layout.md +215 -0
  61. package/docs/es/usage/customizing.md +298 -0
  62. package/docs/es/usage/feedback.md +153 -0
  63. package/docs/es/usage/forms.md +231 -0
  64. package/docs/es/usage/index.md +29 -0
  65. package/docs/es/usage/solo.md +84 -0
  66. package/docs/es/usage/theming.md +296 -0
  67. package/docs/es/usage/tooltips.md +127 -0
  68. package/docs/index.md +85 -26
  69. package/docs/integrating/astro.md +3 -4
  70. package/docs/integrating/index.md +18 -13
  71. package/docs/integrating/nextjs.md +3 -4
  72. package/docs/integrating/svelte.md +5 -4
  73. package/docs/integrating/tailwind.md +16 -3
  74. package/docs/integrating/vue.md +3 -4
  75. package/docs/integrating/without-a-bundler.md +114 -0
  76. package/docs/pt-BR/accessibility.md +150 -0
  77. package/docs/pt-BR/concepts.md +212 -0
  78. package/docs/pt-BR/index.md +104 -0
  79. package/docs/pt-BR/integrating/astro.md +35 -0
  80. package/docs/pt-BR/integrating/index.md +47 -0
  81. package/docs/pt-BR/integrating/nextjs.md +67 -0
  82. package/docs/pt-BR/integrating/svelte.md +45 -0
  83. package/docs/pt-BR/integrating/tailwind.md +78 -0
  84. package/docs/pt-BR/integrating/vue.md +31 -0
  85. package/docs/pt-BR/integrating/without-a-bundler.md +115 -0
  86. package/docs/pt-BR/setup.md +180 -0
  87. package/docs/pt-BR/usage/aesthetics.md +276 -0
  88. package/docs/pt-BR/usage/buttons.md +131 -0
  89. package/docs/pt-BR/usage/composing.md +164 -0
  90. package/docs/pt-BR/usage/content-and-layout.md +215 -0
  91. package/docs/pt-BR/usage/customizing.md +298 -0
  92. package/docs/pt-BR/usage/feedback.md +153 -0
  93. package/docs/pt-BR/usage/forms.md +231 -0
  94. package/docs/pt-BR/usage/index.md +29 -0
  95. package/docs/pt-BR/usage/solo.md +84 -0
  96. package/docs/pt-BR/usage/theming.md +296 -0
  97. package/docs/pt-BR/usage/tooltips.md +127 -0
  98. package/docs/setup.md +134 -91
  99. package/docs/usage/aesthetics.md +76 -66
  100. package/docs/usage/buttons.md +108 -40
  101. package/docs/usage/composing.md +105 -92
  102. package/docs/usage/content-and-layout.md +157 -126
  103. package/docs/usage/customizing.md +107 -37
  104. package/docs/usage/feedback.md +134 -71
  105. package/docs/usage/forms.md +176 -107
  106. package/docs/usage/index.md +18 -14
  107. package/docs/usage/solo.md +83 -0
  108. package/docs/usage/theming.md +260 -118
  109. package/docs/usage/tooltips.md +90 -49
  110. package/llms-full.txt +2358 -1313
  111. package/llms.txt +24 -22
  112. package/package.json +25 -32
  113. package/dist/tw/components/loader.css +0 -116
@@ -2,40 +2,45 @@
2
2
  title: Overview
3
3
  description: How the stylesheet loads in a framework build, and which guide to follow.
4
4
  group: Integrating
5
- order: 4
5
+ order: 2
6
6
  ---
7
7
 
8
8
  # Integrating
9
9
 
10
- This package has no JavaScript and no framework bindings; see [Introduction](../index.md#what-it-does-not-do). Integrating it into a framework is entirely about where that framework lets you load a global stylesheet, and whether the project runs Tailwind CSS v4.
10
+ This section is a detour from the main reading path, for projects whose framework decides where global CSS may go. The package has no JavaScript and no framework bindings (see [Introduction](../index.md#what-it-does-not-do)), so integrating it is only about two things: where your framework lets you load a global stylesheet, and whether the project runs Tailwind CSS v4. Follow the one guide that matches your stack, then return to [Building a screen](../concepts.md).
11
11
 
12
12
  ## The shared model
13
13
 
14
14
  Every stack does the same two imports, from the same kind of place — a root layout, an app entry file, or a global CSS file, never a page or a component further down the tree:
15
15
 
16
- 1. One [entrypoint](../setup.md#import-paths) — the compiled `@codenhub/styles` for any build, or `@codenhub/styles/tw` when the project already runs Tailwind CSS v4.
16
+ 1. One [entrypoint](../setup.md#all-entrypoints) — the compiled `@codenhub/styles` for any build, or `@codenhub/styles/tw` when the project already runs Tailwind CSS v4.
17
17
  2. `@codenhub/styles/aesthetics` (or `/tw/aesthetics`) after it, only if the project uses an [aesthetic](../usage/aesthetics.md).
18
18
 
19
19
  Importing from one place matters for two reasons. Some frameworks only _allow_ global CSS from a designated root file and fail the build otherwise — Next.js's Pages Router is one, see [Next.js → Troubleshooting](./nextjs.md#troubleshooting). Where a framework allows it more broadly, as Next.js's App Router does, importing from the root remains the recommended choice for predictable CSS ordering — and importing per-component instead would load the same reset and token rules once per component rather than once per app.
20
20
 
21
21
  ## Which guide to follow
22
22
 
23
- | Stack | Guide |
24
- | ---------------------------------------- | -------------------------------- |
25
- | A Tailwind CSS v4 project on any bundler | [Tailwind CSS v4](./tailwind.md) |
26
- | Next.js / React | [Next.js](./nextjs.md) |
27
- | Vue | [Vue](./vue.md) |
28
- | Svelte / SvelteKit | [Svelte](./svelte.md) |
29
- | Astro | [Astro](./astro.md) |
23
+ | Stack | Guide |
24
+ | ------------------------------------------------------------ | ------------------------------------------- |
25
+ | A Tailwind CSS v4 project on any bundler | [Tailwind CSS v4](./tailwind.md) |
26
+ | Next.js / React | [Next.js](./nextjs.md) |
27
+ | Vue | [Vue](./vue.md) |
28
+ | Svelte / SvelteKit | [Svelte](./svelte.md) |
29
+ | Astro | [Astro](./astro.md) |
30
+ | Plain HTML, Rails, Django, or any app with no CSS build step | [Without a bundler](./without-a-bundler.md) |
30
31
 
31
- A project with no framework — a plain Vite, webpack, or Parcel build — needs nothing beyond [Setup → Quick start](../setup.md#quick-start): import the compiled stylesheet from the project's existing global CSS entry.
32
+ A project with no framework — a plain Vite, webpack, or Parcel build — needs nothing beyond [Setup → Import the stylesheet](../setup.md#import-the-stylesheet): import the compiled stylesheet from the project's existing global CSS entry.
32
33
 
33
34
  ## Verifying it worked
34
35
 
35
36
  After the import, render one styled element and confirm it picked up the package's tokens rather than the browser default:
36
37
 
37
38
  ```html
38
- <button class="btn primary">Continue</button>
39
+ <button class="btn primary">Save changes</button>
39
40
  ```
40
41
 
41
- A rounded, filled button in the primary color means the stylesheet loaded. Unstyled browser-default text most often means the import specifier didn't resolve — check the [import paths table](../setup.md#import-paths) for the exact one your entrypoint needs, and confirm your build tooling resolves package CSS imports at all, see [Setup → Requirements](../setup.md#requirements).
42
+ A rounded button filled with the primary color (near-black on a light page, near-white on a dark one) means the stylesheet loaded. Unstyled browser-default text most often means the import specifier didn't resolve — check the [entrypoint table](../setup.md#all-entrypoints) for the exact specifier to import, and confirm your build tooling resolves package CSS imports at all, see [Setup → Requirements](../setup.md#requirements). With no build tool, link the file by its path instead; see [Without a bundler](./without-a-bundler.md). [Setup → When nothing is styled](../setup.md#when-nothing-is-styled) lists the other common causes.
43
+
44
+ ## Next
45
+
46
+ Once the button renders, go back to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page.
@@ -47,7 +47,7 @@ Running Tailwind CSS v4? `@import "@codenhub/styles/tw"` is a CSS directive, so
47
47
 
48
48
  ## Force a theme
49
49
 
50
- Apply `.dark` or `.light` on `<html>` to force a theme instead of following the system preference; see [Setup → Configuration](../setup.md#configuration).
50
+ Apply `.dark` or `.light` on `<html>` to force a theme instead of following the system preference; see [Theming → Light and dark](../usage/theming.md#light-and-dark).
51
51
 
52
52
  ```tsx
53
53
  <html lang="en" className="dark">
@@ -61,7 +61,6 @@ Apply `.dark` or `.light` on `<html>` to force a theme instead of following the
61
61
  - **Why:** the Pages Router has no per-route CSS boundary the way the App Router does, so Next.js requires one predictable file for global stylesheets to avoid ordering conflicts between pages.
62
62
  - **Fix:** move the `import "@codenhub/styles"` line to `pages/_app.tsx`, and remove it from wherever it currently is.
63
63
 
64
- ## See also
64
+ ## Next
65
65
 
66
- - [Setup → Import paths](../setup.md#import-paths): every entrypoint this package publishes.
67
- - [Usage](../usage/index.md): component classes to compose once the stylesheet is loaded.
66
+ Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. [Setup → All entrypoints](../setup.md#all-entrypoints) lists every other stylesheet you can import.
@@ -6,6 +6,8 @@ order: 4
6
6
 
7
7
  # Svelte
8
8
 
9
+ Svelte and SvelteKit let you import CSS from any component, but the package's reset and tokens should load once, before any component renders. This page shows where that one import goes in SvelteKit and in a plain Svelte app.
10
+
9
11
  ## Import the stylesheet
10
12
 
11
13
  **SvelteKit** — import from the root layout so it loads once for every route:
@@ -35,9 +37,8 @@ Running Tailwind CSS v4? Import `@codenhub/styles/tw` from the app's CSS entry i
35
37
 
36
38
  ## Force a theme
37
39
 
38
- Apply `.dark` or `.light` on `<html>` (edit `src/app.html` in SvelteKit) to force a theme instead of following the system preference; see [Setup → Configuration](../setup.md#configuration).
40
+ Apply `.dark` or `.light` on `<html>` (edit `src/app.html` in SvelteKit) to force a theme instead of following the system preference; see [Theming → Light and dark](../usage/theming.md#light-and-dark).
39
41
 
40
- ## See also
42
+ ## Next
41
43
 
42
- - [Setup → Import paths](../setup.md#import-paths): every entrypoint this package publishes.
43
- - [Usage](../usage/index.md): component classes to compose once the stylesheet is loaded.
44
+ Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. [Setup → All entrypoints](../setup.md#all-entrypoints) lists every other stylesheet you can import.
@@ -6,7 +6,7 @@ order: 1
6
6
 
7
7
  # Tailwind CSS v4
8
8
 
9
- A project that already runs Tailwind CSS v4 can process this package's source instead of its compiled output, so both sets of classes compile through the same Tailwind build.
9
+ A project that already runs Tailwind CSS v4 can compile this package's source instead of loading its compiled output. Your app's utilities and the package's classes then come out of one build, share one theme, and use one `dark:` variant. This page covers the import, aesthetics, the focused entrypoints, and the build problems you are likely to meet.
10
10
 
11
11
  ## Why source instead of compiled
12
12
 
@@ -37,14 +37,13 @@ Add an aesthetic from the source entrypoint the same way as the compiled one, af
37
37
 
38
38
  ## Using a focused entrypoint
39
39
 
40
- Import a focused `/tw/*` entrypoint instead of the combined one — such as `/tw/button` or `/tw/form` — when a build only needs one component family; see the full [import path table](../setup.md#import-paths) for what each one composes.
40
+ Import a focused `/tw/*` entrypoint instead of the combined one — such as `/tw/button` or `/tw/form` — when a build only needs one component family; see the full [entrypoint table](../setup.md#all-entrypoints) for what each one composes.
41
41
 
42
42
  Unlike `/tw`, the focused entrypoints and `/tw/native` do not import Tailwind, so keep your own import first:
43
43
 
44
44
  ```css
45
45
  @import "tailwindcss";
46
46
  @import "@codenhub/styles/tw/button";
47
- @import "@codenhub/styles/tw/loader";
48
47
  ```
49
48
 
50
49
  ## Troubleshooting
@@ -61,4 +60,18 @@ Unlike `/tw`, the focused entrypoints and `/tw/native` do not import Tailwind, s
61
60
  - **Why:** one of two things. Importing both a compiled entrypoint (`@codenhub/styles`) and a `/tw` entrypoint (`@codenhub/styles/tw`) in the same build compiles the same tokens and reset from two independent sources; Tailwind's build has no way to know they describe the same package. Or your stylesheet imports `tailwindcss` beside `/tw`, which already imports it, so Preflight is emitted twice.
62
61
  - **Fix:** pick one path per project — `/tw` entrypoints for a project running Tailwind CSS v4, compiled entrypoints everywhere else — and drop your own `@import "tailwindcss"` when you import `/tw`.
63
62
 
63
+ **A class built at runtime has no styling**
64
+
65
+ - **What happened:** `<button class="btn primary">` is styled, but a button whose intent comes from a variable, such as `` `btn ${tone}` ``, is not.
66
+ - **Why:** Tailwind generates a class only when it finds the complete name in your source files. The package's own component and axis classes are always generated, but your own utilities are not, and a name assembled from strings is invisible to the scan.
67
+ - **Fix:** write complete class names in your source, for example in a lookup object (`{ save: "btn primary", remove: "btn destructive" }`), or list the names your code can produce with `@source inline("...")` in your stylesheet.
68
+
64
69
  Every `/tw` entrypoint requires Tailwind CSS 4.3.2 or newer, below 5: the source uses `@source not` and `@source inline()`, which arrived in 4.1, and it is tested against 4.3.2.
70
+
71
+ ## The `dark:` variant
72
+
73
+ The `/tw` entrypoints define their own `dark:` variant, so your utilities switch with the same light and dark selectors the package's tokens use. It has one known difference from the tokens when themes are nested; see [Theming → The dark: variant](../usage/theming.md#the-dark-variant).
74
+
75
+ ## Next
76
+
77
+ Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. Everything it shows works the same on `/tw`.
@@ -23,9 +23,8 @@ Running Tailwind CSS v4? Import `@codenhub/styles/tw` from a CSS entry file inst
23
23
 
24
24
  ## Force a theme
25
25
 
26
- Apply `.dark` or `.light` on the root element to force a theme instead of following the system preference; see [Setup → Configuration](../setup.md#configuration).
26
+ Apply `.dark` or `.light` on the root element to force a theme instead of following the system preference; see [Theming → Light and dark](../usage/theming.md#light-and-dark).
27
27
 
28
- ## See also
28
+ ## Next
29
29
 
30
- - [Setup → Import paths](../setup.md#import-paths): every entrypoint this package publishes.
31
- - [Usage](../usage/index.md): component classes to compose once the stylesheet is loaded.
30
+ Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. [Setup → All entrypoints](../setup.md#all-entrypoints) lists every other stylesheet you can import.
@@ -0,0 +1,114 @@
1
+ ---
2
+ title: Without a bundler
3
+ description: Linking the compiled stylesheets from plain HTML, Rails, Django, or any server-rendered app.
4
+ order: 6
5
+ ---
6
+
7
+ # Without a bundler
8
+
9
+ The compiled stylesheets are finished CSS: each one is a single file with no `@import` and no reference to another file, and every image it draws is embedded as a `data:` URL: the checkbox tick and dash masks, and the SVG lens filters `.glass-liquid` uses. A page can load one with a plain `<link>` tag, from any server, with no build step, and the stylesheet makes no further requests.
10
+
11
+ What needs a build tool is the import _name_. `@import "@codenhub/styles"` names a package, and finding the file behind that name — `node_modules/@codenhub/styles/dist/index.css` — is done by Node-aware tooling such as Vite, webpack, or the Tailwind CLI, which read the package's `exports` map. A browser does not: it resolves an `@import` URL against the stylesheet that contains it and a `<link href>` against the page, so a bare package name becomes a request for a path that does not exist. Without a bundler, link the file by its path instead.
12
+
13
+ The `/tw` entrypoints are Tailwind source and need a Tailwind build. `/tw/aesthetics` is the exception, plain CSS with nothing for Tailwind to process, but without a bundler link the compiled `dist/aesthetics/` files instead, as below. This page covers the compiled entrypoints only, for a page that has no CSS build at all: plain HTML, Rails, Django, or any server-rendered app.
14
+
15
+ ## Which file to link
16
+
17
+ Each compiled import path is one file in the package's `dist/` folder:
18
+
19
+ | Import path | File |
20
+ | ------------------------------- | ----------------------------------------------------------------- |
21
+ | `@codenhub/styles` | `dist/index.css` |
22
+ | `@codenhub/styles/theme` | `dist/theme.css` |
23
+ | `@codenhub/styles/components` | `dist/components.css` |
24
+ | `@codenhub/styles/native` | `dist/native.css` |
25
+ | `@codenhub/styles/palette` | `dist/palette.css` |
26
+ | `@codenhub/styles/aesthetics` | `dist/aesthetics/index.css` |
27
+ | `@codenhub/styles/aesthetics/*` | `dist/aesthetics/<name>.css`, such as `dist/aesthetics/pixel.css` |
28
+
29
+ Link the base file first and an aesthetic after it. [Setup → All entrypoints](../setup.md#all-entrypoints) explains what each one contains; link one base file, not several, since they overlap.
30
+
31
+ ## From a CDN
32
+
33
+ jsDelivr and unpkg serve every file of every published npm version, so a page can link one with nothing installed:
34
+
35
+ ```html
36
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codenhub/styles@0.7.0/dist/index.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codenhub/styles@0.7.0/dist/aesthetics/pixel.css" />
37
+ ```
38
+
39
+ Put the exact version in the URL. Without one, the CDN serves the latest release, and below 1.0 a minor release may rename or remove a class; see [Versioning](../index.md#versioning).
40
+
41
+ ## From your own server
42
+
43
+ Install the package, then serve its `dist/` folder as static files:
44
+
45
+ ```sh
46
+ npm install @codenhub/styles
47
+ ```
48
+
49
+ How a framework serves a folder from `node_modules` differs, so each one is below. Where the framework reads the folder in place, as Rails and Django do, upgrading the package and redeploying is all an update takes.
50
+
51
+ ### Plain HTML
52
+
53
+ Copy `node_modules/@codenhub/styles/dist` into the folder your server publishes, then link it:
54
+
55
+ ```html
56
+ <link rel="stylesheet" href="/vendor/codenhub-styles/index.css" />
57
+ ```
58
+
59
+ Repeat the copy after each upgrade, for example from an npm `postinstall` script.
60
+
61
+ ### Ruby on Rails
62
+
63
+ A Rails app built with `cssbundling-rails` already runs a bundler: import the package from `app/assets/stylesheets/application.css` as in [Setup → Import the stylesheet](../setup.md#import-the-stylesheet).
64
+
65
+ With Propshaft and no CSS bundler, add the package's folder to the asset paths:
66
+
67
+ ```ruby
68
+ # config/initializers/assets.rb
69
+ Rails.application.config.assets.paths << Rails.root.join("node_modules/@codenhub")
70
+ ```
71
+
72
+ Then link it from the layout, by its path below that folder:
73
+
74
+ ```erb
75
+ <%# app/views/layouts/application.html.erb %>
76
+ <%= stylesheet_link_tag "styles/dist/index" %>
77
+ <%= stylesheet_link_tag "styles/dist/aesthetics/pixel" %>
78
+ ```
79
+
80
+ Point the path at `node_modules/@codenhub` rather than at `dist/` itself. Propshaft serves files by their path below each asset folder, so adding `dist/` directly would publish a bare `index.css` that collides with any `index.css` of your own.
81
+
82
+ ### Django
83
+
84
+ Add the folder to `STATICFILES_DIRS` under a prefix, which keeps its file names apart from your own static files:
85
+
86
+ ```python
87
+ # settings.py
88
+ STATICFILES_DIRS = [
89
+ ("codenhub-styles", BASE_DIR / "node_modules/@codenhub/styles/dist"),
90
+ ]
91
+ ```
92
+
93
+ ```django
94
+ {% load static %}
95
+ <link rel="stylesheet" href="{% static 'codenhub-styles/index.css' %}" />
96
+ ```
97
+
98
+ ### Laravel
99
+
100
+ A Laravel app runs Vite by default, so it has a bundler: import the package from `resources/css/app.css` as in [Setup → Import the stylesheet](../setup.md#import-the-stylesheet), and load that file with the `@vite` directive as usual.
101
+
102
+ ## Verifying it worked
103
+
104
+ Render one styled element, as in [Integrating → Verifying it worked](./index.md#verifying-it-worked):
105
+
106
+ ```html
107
+ <button class="btn primary">Save changes</button>
108
+ ```
109
+
110
+ A rounded button filled with the primary color means the stylesheet loaded. If the button looks like the browser default, open the browser's network panel: a `404` on the stylesheet means the path or the static-file setup is wrong.
111
+
112
+ ## Next
113
+
114
+ Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. [Setup → All entrypoints](../setup.md#all-entrypoints) lists every other stylesheet you can import.
@@ -0,0 +1,150 @@
1
+ ---
2
+ title: Acessibilidade
3
+ description: O que o CSS faz por foco, estados, movimento, contraste, cores forçadas e texto da direita para a esquerda, e o que a sua aplicação ainda deve aos seus usuários.
4
+ order: 5
5
+ source: dc1a745e9e6853a31ca4a8cf7a334031bab1ec7d
6
+ ---
7
+
8
+ # Acessibilidade
9
+
10
+ A tela de configurações está pronta, e o CSS fez a sua parte no caminho: todo campo mostra onde está o foco, um email inválido fica vermelho e o spinner para para usuários que pedem menos movimento. O resto depende do seu HTML e JavaScript. Este pacote estiliza estados; ele não fornece elementos semânticos, atributos ARIA, comportamento de teclado, gerenciamento de foco, validação nem o momento dos anúncios.
11
+
12
+ Esta página lista as duas metades: o que o CSS fornece e o que a sua aplicação precisa adicionar.
13
+
14
+ ## Fornecido pelo CSS
15
+
16
+ ### Foco e estado
17
+
18
+ | Recurso | Comportamento |
19
+ | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
20
+ | `:focus-visible` | Um outline de foco em todo elemento, desenhado com `--focus-ring`, `--focus-ring-width` e `--focus-ring-offset`. |
21
+ | Foco em controles de formulário | `.ipt`, `.textarea` e `.select` desenham o outline de foco e mudam a borda para a cor da intenção. O texto digitado num campo com classe de intenção fica no tom legível da intenção, `--intent-strong`. |
22
+ | Controles inválidos | `aria-invalid="true"` num controle de formulário deixa a borda, a cor de foco e o texto digitado na cor destrutiva, com o texto no tom legível destrutivo. |
23
+ | Controles desabilitados | `disabled`, `aria-disabled="true"`, `data-disabled` e `.disabled` mostram o cursor e a opacidade de desabilitado, e um controle desabilitado não reage ao hover, inclusive dentro de um `.input-group`. |
24
+ | Estado aberto | `data-state="open"` num `.tooltip` mostra o balão sem hover nem foco, e `data-state="closed"` o esconde durante o hover ou o foco. Nenhum outro componente lê nenhum dos dois. |
25
+ | `<dialog>` nativo | Um `<dialog>` com `.card`, `.panel` ou `.surface` fica escondido até ser aberto, e abre centralizado. Uma margem que você define no dialog, como utilitário ou no seu próprio CSS, ainda substitui a centralização. Outros dialogs não são afetados. Prender o foco, fechar com Escape e tornar inerte a página por trás ficam por conta da sua aplicação. |
26
+
27
+ ### Conteúdo visualmente oculto
28
+
29
+ `.visually-hidden` esconde o conteúdo na tela e o mantém para leitores de tela, como faz a `<caption>` da tabela de chaves de API em [Conteúdo e layout → Tabelas](./usage/content-and-layout.md#tabelas). Ela vem com os utilitários de layout: em `.`, `./native`, `./tw`, `./tw/native` e `./tw/utilities`. Ela não está em `./components` nem nos entrypoints de componentes `./tw/components` e `./tw/*`.
30
+
31
+ ### Limites dos controles
32
+
33
+ O WCAG 1.4.11 pede que o limite de um controle que você precisa ver para usá-lo tenha um contraste de pelo menos 3:1 em relação ao que está ao lado dele.
34
+
35
+ | Recurso | Comportamento |
36
+ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
37
+ | Controles de texto em repouso | A borda de um controle de texto fica, em repouso, mais clara que a borda cheia da sua intenção, abaixo de 3:1 por escolha, para que o hover e o foco tenham um tom mais forte para onde mudar. |
38
+ | Toggles | `.checkbox`, `.radio` e `.switch` desenham a borda cheia, porque a borda é a única coisa que mostra uma caixa desmarcada. Um `.switch` com o seu próprio `.edgeless` é a exceção, abaixo. |
39
+ | `.edgeless` vindo de um contêiner | Ignorado por todo controle de texto e toggle: um contêiner não pode remover a borda de um campo ou toggle dentro dele. |
40
+ | `.edgeless` no próprio controle | `.ipt`, `.textarea`, `.select` e `.switch` perdem a borda e deixam de atender ao 1.4.11 em repouso. `.switch.ghost` mantém a borda mesmo assim, porque, sem preenchimento e sem borda, nada mostraria o trilho. |
41
+ | `.checkbox`, `.radio` | Sempre desenham a borda, venha o `.edgeless` de um contêiner ou deles mesmos. `.edgeless` neles não é suportado. |
42
+ | Trilho de progresso | Por escolha, a parte preenchida carrega o valor e o trilho é um fundo discreto. O trilho padrão, `.soft.edgeless`, mede cerca de 1.1:1 a 1.3:1 em relação à página. A parte preenchida mede pelo menos 3:1 em relação a esse trilho em todas as intenções, exceto warning no claro (cerca de 2.7:1) e info no escuro (cerca de 2.9:1). Onde o próprio trilho precisa atender ao 1.4.11, use `.ghost.edged` com uma classe de intenção; veja [Contornos de progresso](#contornos-de-progresso) abaixo. |
43
+
44
+ ### Contornos de progresso
45
+
46
+ Num `.progress.ghost.edged`, o trilho é a página, e o seu contorno e a parte preenchida são desenhados na cor da intenção. Medido em relação à página, sem estética:
47
+
48
+ | Intenção | Página clara | Página escura | Atende a 3:1 |
49
+ | -------------- | ------------ | ------------- | ------------------------------------------------------------------------ |
50
+ | `.primary` | 18.96:1 | 18.96:1 | Sim |
51
+ | `.secondary` | 7.47:1 | 7.63:1 | Sim |
52
+ | `.success` | 5.14:1 | 3.69:1 | Sim |
53
+ | `.warning` | 3.06:1 | 6.20:1 | Sim |
54
+ | `.destructive` | 5.80:1 | 3.27:1 | Sim |
55
+ | `.info` | 6.17:1 | 3.07:1 | Sim |
56
+ | Sem intenção | 2.48:1 | 1.91:1 | Não: o contorno falha, embora a parte preenchida, na cor do texto, passe |
57
+
58
+ Sem classe de intenção, o contorno é o cinza de borda discreto, `--color-border`. Para que um trilho neutro atenda ao 1.4.11, dê uma classe de intenção à barra, ou defina `--progress-edge` com uma cor mais forte, como `var(--color-accent)`, que mede 7.47:1 numa página clara e 7.63:1 numa escura. Warning numa página clara e info numa escura passam de 3:1 por pouco, então meça de novo se você mudar essas cores.
59
+
60
+ ### Movimento e transparência
61
+
62
+ | Recurso | Comportamento |
63
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
64
+ | Movimento reduzido, componentes | Com `prefers-reduced-motion: reduce`, todo componente para as suas próprias transições e animações: o brilho do skeleton e do progresso, a barra indeterminada, o tooltip, as marcas dos toggles e o clique. |
65
+ | Movimento reduzido, página inteira | O reset também encurta todas as outras animações e transições da página. |
66
+ | Transparência reduzida | Com `prefers-reduced-transparency: reduce`, `.glass` e `.glass-liquid` perdem o desfoque e a lente e ficam opacos. |
67
+
68
+ A regra de movimento reduzido de cada componente vem com o componente, então todo entrypoint que o inclui respeita o movimento reduzido sem o reset, incluindo `@codenhub/styles/components`, `@codenhub/styles/tw/components` e cada entrypoint de componente `/tw/*`. Os entrypoints completos e nativos adicionam a regra do reset para a página inteira.
69
+
70
+ A regra do reset é `!important` dentro da camada `base`, e um `!important` com camada vence um sem camada, então o seu próprio `!important` não consegue religar uma animação. Para manter uma rodando para usuários que pedem movimento reduzido, como um spinner de upload que você considera essencial, declare-a `!important` numa camada ordenada antes de `base`. A primeira declaração `@layer` que o navegador lê define a ordem, então a sua vem antes do pacote:
71
+
72
+ ```css
73
+ @layer essential-motion, theme, base, components, utilities;
74
+ @import "@codenhub/styles";
75
+
76
+ @layer essential-motion {
77
+ @media (prefers-reduced-motion: reduce) {
78
+ .upload-spinner {
79
+ animation-duration: 1s !important;
80
+ animation-iteration-count: infinite !important;
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ Respeitar o movimento reduzido não é o requisito inteiro. Um movimento que continua ao lado do conteúdo, como um brilho deixado num card depois que ele carregou, precisa de uma forma de ser parado por qualquer usuário; veja [Feedback → Animação que não para](./usage/feedback.md#animação-que-não-para).
87
+
88
+ ### Cor e contraste
89
+
90
+ As medições abaixo são das cores entregues. Assim que você mudar um token de cor, meça de novo os seus próprios pares; [Temas → Mude a cor da marca](./usage/theming.md#mude-a-cor-da-marca) mostra quais pares conferir.
91
+
92
+ | Recurso | Comportamento |
93
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
94
+ | Rótulos preenchidos | O rótulo `.solid` de toda intenção atende a 4.5:1 (WCAG 1.4.3) como texto normal, nos dois temas. O menor é success, com 5.14:1. |
95
+ | Texto em warning | `--color-warning-contrast` é quase preto, e não a cor da página, porque um âmbar escuro o bastante para carregar texto branco deixa de parecer âmbar. |
96
+ | Preenchimentos parciais | A cor de texto de contraste só aparece em preenchimentos acima da metade da força, então o preenchimento limitado de um controle de texto mantém a cor de texto da própria intenção. |
97
+ | Cor da intenção no escuro | No modo escuro, um rótulo `.soft` ou `.ghost` usa o tom `-300` da sua intenção, para manter o matiz em vez de ficar branco. |
98
+ | Marcas dos toggles | Uma marca de marcado mede pelo menos 3:1 em relação a todo preenchimento que a sua apresentação pode dar a ela, nos dois temas. |
99
+ | Preenchimentos soft com borda | `.edged` num `.alert`, `.panel`, `.badge`, `.kbd`, `.code` ou `.pre` `.soft` desenha uma borda que mede menos de 3:1 em relação ao preenchimento de 12% em algumas intenções, que variam conforme o tema. Meça o par antes de contar com essa borda como limite de um controle. |
100
+
101
+ ### Cores forçadas e direção
102
+
103
+ | Recurso | Comportamento |
104
+ | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
105
+ | Cores forçadas | Com `forced-colors: active`, as bordas, os estados marcados e a seta de um `.select` continuam visíveis, desenhados nas cores do sistema, sob todas as estéticas. Uma estética que desenha a borda como sombra interna, como `.pixel`, desenha uma borda real no lugar. |
106
+ | Direção do texto | Sob `dir="rtl"`, a barra da citação, o ícone do alerta, o preenchimento do progresso, o divisor vertical, o botão do switch, o alinhamento das tabelas e a seta de um select trocam de lado. Nenhuma classe é necessária. |
107
+
108
+ Em cores forçadas, `.text-control`, `.ipt`, `.textarea`, `.select` e os toggles mostram um outline de foco `Highlight` de 2px. O entrypoint nativo dá o mesmo outline a campos de texto, selects, textareas, checkboxes e radios sem classe.
109
+
110
+ Checkboxes, radios e switches usam as cores do sistema `Canvas`, `CanvasText`, `Highlight` e `HighlightText`, para que marcado e desmarcado continuem distintos: um toggle marcado é preenchido com `Highlight` e a sua marca é `HighlightText`, tanto nas classes quanto no entrypoint nativo. Formato, tamanho e espaçamento não mudam.
111
+
112
+ ## O que fica fora do CSS
113
+
114
+ Use o elemento HTML que corresponde ao que o componente faz e adicione o comportamento que o CSS não consegue.
115
+
116
+ | Interface | O que a sua aplicação adiciona |
117
+ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
118
+ | Botões | `<button>` para ações e `<a href>` para navegação. Um nome acessível, como `aria-label`, em todo `.btn.icon`. |
119
+ | Formulários | Um `<label>` para cada controle, o `type` certo, validação e `aria-describedby` ligando dicas e erros. Mantenha dicas e erros fora do `<label>` e dê `role="switch"` a um `.switch`. |
120
+ | Alertas | `role="status"` para uma confirmação como "Profile saved", ou `role="alert"` para um erro que precisa de atenção imediata. |
121
+ | Toasts | Uma live region, uma forma de dispensá-lo, regras de foco e uma pausa em qualquer tempo limite. |
122
+ | Tooltips | Um `id` real e `role="tooltip"` no balão, referenciado pelo `aria-describedby` do gatilho. Dispensa com Escape escrevendo `data-state="closed"`; veja [Tooltips](./usage/tooltips.md#hover-permanência-e-escape). O balão já aceita hover. |
123
+ | Progresso | Um elemento `<progress>`, ou `role="progressbar"` ou `role="meter"` com valores ARIA, quando o valor precisa ser anunciado. |
124
+ | Skeletons | `aria-hidden="true"` nos visuais de carregamento, incluindo um spinner que você traga, e o estado de carregamento anunciado de outra forma quando necessário. |
125
+ | Movimento contínuo | Uma forma de pausar, parar ou esconder o movimento que não é essencial; veja [Feedback → Animação que não para](./usage/feedback.md#animação-que-não-para). |
126
+ | Popovers, modais | Prender o foco, fechar com Escape, um fundo inerte, rótulos e roles. |
127
+
128
+ ## Atributos de estado
129
+
130
+ Prefira os atributos nativos:
131
+
132
+ ```html
133
+ <button class="btn primary" disabled>Saving…</button> <input class="ipt" type="email" aria-invalid="true" aria-describedby="email-error" />
134
+ ```
135
+
136
+ Use atributos ARIA ou data onde o elemento ou a sua biblioteca de componentes não tem um nativo:
137
+
138
+ ```html
139
+ <a class="btn secondary" aria-disabled="true">Export data</a>
140
+ <span class="tooltip" data-state="open">
141
+ <button type="button" class="tooltip-icon" aria-label="About public profiles" aria-describedby="public-profile-help">?</button>
142
+ <span class="tooltip-bubble" role="tooltip" id="public-profile-help">Anyone with the link can see your name and photo.</span>
143
+ </span>
144
+ ```
145
+
146
+ `aria-disabled="true"` informa às tecnologias assistivas que o controle está desabilitado, mas não impede um clique nem o pressionar de uma tecla. Use o atributo `disabled`, ou interrompa a ação no JavaScript.
147
+
148
+ ## A seguir
149
+
150
+ Isso completa a ordem de leitura. A [Introdução](./index.md) tem links para todas as páginas, e [Composição](./usage/composing.md), [Personalização](./usage/customizing.md) e [Conteúdo e layout](./usage/content-and-layout.md) são as páginas de consulta para depois.