@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
@@ -27,9 +27,8 @@ Every page that uses this layout loads the stylesheet once. Running Tailwind CSS
27
27
 
28
28
  ## Force a theme
29
29
 
30
- Apply `.dark` or `.light` on `<html>` to force a theme instead of following the system preference; see [Setup → Configuration](../setup.md#configuration).
30
+ 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).
31
31
 
32
- ## See also
32
+ ## Next
33
33
 
34
- - [Setup → Import paths](../setup.md#import-paths): every entrypoint this package publishes.
35
- - [Usage](../usage/index.md): component classes to compose once the stylesheet is loaded.
34
+ 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.
@@ -2,40 +2,73 @@
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, Laravel, Django, or any app with no Node.js 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 — imports the compiled stylesheet from the project's existing global CSS entry, as [Setup → Import the stylesheet](../setup.md#import-the-stylesheet) shows. Vite and webpack resolve the package name as it is; Parcel and PostCSS with `postcss-import` need the change below. The compiled stylesheet holds every class; to ship only the ones your pages use without adopting Tailwind, write a trimmed stylesheet with the package's [`build` command](./without-a-bundler.md#build-only-the-classes-you-use) and import that instead.
33
+
34
+ ### Bundlers that need a nudge
35
+
36
+ Both tools find the stylesheet once they are told how; neither needs a different entrypoint.
37
+
38
+ **Parcel.** Turn on its support for a package's `exports` map in your `package.json`:
39
+
40
+ ```json
41
+ {
42
+ "@parcel/resolver-default": {
43
+ "packageExports": true
44
+ }
45
+ }
46
+ ```
47
+
48
+ Then import the package with Parcel's `npm:` prefix, which tells it the name is a package and not a file next to the stylesheet:
49
+
50
+ ```css
51
+ @import "npm:@codenhub/styles";
52
+ ```
53
+
54
+ **PostCSS with `postcss-import`.** The plugin does not read a package's `exports` map, so the package name alone does not resolve. Import the compiled file by its path on disk instead, relative to your own stylesheet, the same file a `<link>` would name:
55
+
56
+ ```css
57
+ @import "../node_modules/@codenhub/styles/dist/index.css";
58
+ ```
59
+
60
+ The other compiled entrypoints work the same way, such as `@codenhub/styles/dist/aesthetics/neobrutalism.css`.
32
61
 
33
62
  ## Verifying it worked
34
63
 
35
64
  After the import, render one styled element and confirm it picked up the package's tokens rather than the browser default:
36
65
 
37
66
  ```html
38
- <button class="btn primary">Continue</button>
67
+ <button class="btn primary">Save changes</button>
39
68
  ```
40
69
 
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).
70
+ 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.
71
+
72
+ ## Next
73
+
74
+ 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,11 +6,11 @@ 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, building your own components with `@apply`, dropping Tailwind's palette, and the build problems you are likely to meet.
10
10
 
11
11
  ## Why source instead of compiled
12
12
 
13
- `/tw` entrypoints publish copied, uncompiled source from `dist/tw`; your own Tailwind build compiles it alongside your app, so its `@theme`, `@utility`, and `@apply` directives resolve together with yours. The compiled entrypoints (`@codenhub/styles`) still work in a Tailwind project, but then two separate CSS pipelines run side by side instead of one — use `/tw` unless a specific reason rules it out.
13
+ `/tw` entrypoints publish copied, uncompiled source from the package's `tw/` folder; your own Tailwind build compiles it alongside your app, so its `@theme`, `@utility`, and `@apply` directives resolve together with yours. The compiled entrypoints (`@codenhub/styles`) still work in a Tailwind project, but then two separate CSS pipelines run side by side instead of one — use `/tw` unless a specific reason rules it out.
14
14
 
15
15
  ## Import the source entrypoint
16
16
 
@@ -22,7 +22,7 @@ A project that already runs Tailwind CSS v4 can process this package's source in
22
22
 
23
23
  `/tw` imports Tailwind itself, so it replaces your own `@import "tailwindcss"` rather than joining it: with both, Tailwind's Preflight is emitted twice. Every other `/tw/*` entrypoint expects your import to come first; see [Using a focused entrypoint](#using-a-focused-entrypoint).
24
24
 
25
- Tailwind CSS v4 scans your project automatically — most projects need nothing beyond the import above. `@source` paths resolve relative to the CSS file that declares them, not your project root, so `./src` here means "the `src/` next to this stylesheet"; adjust it to match where your own global stylesheet actually lives. Add `@source` only for markup Tailwind's automatic scan won't reach on its own: a path excluded by default (`.gitignore`d, or inside `node_modules` — an external component library, for instance) or, in a monorepo, one outside this file's own directory tree. Point it at your app's markup, not at this package — `/tw` already ships every class definition it publishes, so scanning it too only slows the build without adding classes.
25
+ Tailwind CSS v4 scans your project automatically — most projects need nothing beyond the import above. `@source` paths resolve relative to the CSS file that declares them, not your project root, so `./src` here means "the `src/` next to this stylesheet"; adjust it to match where your own global stylesheet actually lives. Add `@source` only for markup Tailwind's automatic scan won't reach on its own: a path excluded by default (`.gitignore`d, or inside `node_modules` — an external component library, for instance) or, in a monorepo, one outside this file's own directory tree. Point it at your app's markup, not at this package: the package's source names every class it defines, so scanning it emits all of them whether your pages use them or not.
26
26
 
27
27
  ## Add aesthetics
28
28
 
@@ -37,16 +37,79 @@ 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
 
49
+ ## Build your own components with `@apply`
50
+
51
+ On `/tw`, every component, helper, and axis class is a Tailwind utility. That includes the intents (`neutral`, `primary`, `secondary`, `success`, `warning`, `destructive`, `info`), the presentation (`solid`, `soft`, `ghost`, `edged`, `edgeless`), the elevation (`flat`, `raised`, `floating`), the corner patterns (`cut-diagonal`, `cut-diagonal-reverse`), and the sizes (`sm`, `lg`). So one class of yours can carry a whole recipe:
52
+
53
+ ```css
54
+ @import "@codenhub/styles/tw";
55
+
56
+ @utility btn-save {
57
+ @apply btn primary soft sm;
58
+ }
59
+
60
+ @utility btn-danger {
61
+ @apply btn destructive md:lg dark:solid;
62
+ }
63
+ ```
64
+
65
+ ```html
66
+ <button class="btn-save" type="submit">Save</button>
67
+ ```
68
+
69
+ - **An applied component behaves like the class.** `btn-save` hovers, presses, takes focus, and follows an aesthetic the way `class="btn primary soft sm"` does.
70
+ - **Variants work.** `hover:primary`, `md:lg`, and `dark:solid` apply an axis class under that condition, in your markup or inside `@apply`.
71
+ - **Write your class as `@utility`.** It then stays in the `utilities` layer, so your other utilities on the same element still beat it. A plain `.btn-save { @apply … }` rule works too, but it is unlayered, so what it applies beats every utility on the element; [Customizing → Composition helpers](../usage/customizing.md#composition-helpers) has the details.
72
+ - **Modifiers apply too.** A component's modifiers, such as `.tight` on `.stack`, `.icon` on `.btn`, or `.interactive` on `.card`, are utilities as well, so `@apply stack tight`, `@apply btn icon pill`, and `md:tight` work. The disabled state is the exception: it stays an attribute or the `.disabled` class in markup.
73
+ - **Your utility beats a component's inner defaults.** `p-0 text-center` on a `.data-table` cell, `text-sm` on a `.label`, and `px-8` on a `.btn.sm` all apply.
74
+
75
+ [Presets](../usage/presets.md) compares this with the other ways to set a look once.
76
+
77
+ ## Drop Tailwind's palette
78
+
79
+ `/tw` builds on Tailwind's default theme, so Tailwind's palette utilities, such as `bg-red-500`, stay available. If your design uses only the package's tokens, clear the hues you do not use:
80
+
81
+ ```css
82
+ @import "@codenhub/styles/tw";
83
+
84
+ @theme {
85
+ --color-red-*: initial;
86
+ --color-orange-*: initial;
87
+ --color-yellow-*: initial;
88
+ --color-lime-*: initial;
89
+ --color-green-*: initial;
90
+ --color-teal-*: initial;
91
+ --color-cyan-*: initial;
92
+ --color-sky-*: initial;
93
+ --color-blue-*: initial;
94
+ --color-violet-*: initial;
95
+ --color-purple-*: initial;
96
+ --color-fuchsia-*: initial;
97
+ --color-pink-*: initial;
98
+ --color-slate-*: initial;
99
+ --color-gray-*: initial;
100
+ --color-zinc-*: initial;
101
+ --color-stone-*: initial;
102
+ --color-black: initial;
103
+ }
104
+ ```
105
+
106
+ The package's own colors do not change, and you can still add colors of your own in the same block.
107
+
108
+ The block leaves out `neutral`, `emerald`, `amber`, `rose`, `indigo`, and `white` on purpose: the theme builds its colors from them.
109
+
110
+ - **Do not clear the whole namespace.** `--color-*: initial` also removes the package's semantic colors, and the build stops with an error such as `Cannot apply unknown utility class`.
111
+ - **Do not clear a ramp the theme reads.** Clearing `--color-emerald-*` builds without an error, but the success colors made from it are lost.
112
+
50
113
  ## Troubleshooting
51
114
 
52
115
  **Classes resolve to no styling**
@@ -61,4 +124,24 @@ Unlike `/tw`, the focused entrypoints and `/tw/native` do not import Tailwind, s
61
124
  - **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
125
  - **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
126
 
64
- 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.
127
+ **A class built at runtime has no styling**
128
+
129
+ - **What happened:** `<button class="btn primary">` is styled, but a button whose class comes from a variable, such as `"btn " + variant`, or from CMS content, is not.
130
+ - **Why:** Tailwind emits only the classes it finds written out in the files it scans. That holds for the package's component classes too: a `/tw` build emits `.alert` only if `alert` appears somewhere it scans, which keeps the stylesheet to what your pages use. The intent, presentation, elevation, corner, and size classes, such as `.primary`, `.soft`, and `.sm`, are utilities too, so the same holds for them. The aesthetic classes, such as `.glass`, are plain CSS and always emitted. A name assembled at runtime never appears whole in a file, so the scan misses it.
131
+ - **Fix:** write each complete class name somewhere Tailwind scans, for example in a lookup object (`{ save: "btn primary", remove: "btn destructive" }`), or list the names your code or content can produce in your stylesheet:
132
+
133
+ ```css
134
+ @import "@codenhub/styles/tw";
135
+
136
+ @source inline("btn alert badge primary destructive soft");
137
+ ```
138
+
139
+ Every `/tw` entrypoint requires Tailwind CSS 4.3.2 or newer, below 5 (`>=4.3.2 <5`).
140
+
141
+ ## The `dark:` variant
142
+
143
+ 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).
144
+
145
+ ## Next
146
+
147
+ 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,237 @@
1
+ ---
2
+ title: Without a bundler
3
+ description: Linking the compiled stylesheets from plain HTML, Rails, Laravel, Django, or any server-rendered app, and the command-line build.
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 is for a page that has no Node.js CSS build: plain HTML, Rails, Laravel, Django, or any server-rendered app. There are two paths:
14
+
15
+ 1. **Link the compiled stylesheet.** Works today, with nothing but static files. You ship every class, whether your pages use it or not.
16
+ 2. **Build a stylesheet with the package's `build` command.** It scans your templates and writes a stylesheet with only the classes they use. See [Build only the classes you use](#build-only-the-classes-you-use).
17
+
18
+ ## Which file to link
19
+
20
+ Each compiled import path is one file in the package's `dist/` folder:
21
+
22
+ | Import path | File |
23
+ | ------------------------------- | ----------------------------------------------------------------- |
24
+ | `@codenhub/styles` | `dist/index.css` |
25
+ | `@codenhub/styles/theme` | `dist/theme.css` |
26
+ | `@codenhub/styles/components` | `dist/components.css` |
27
+ | `@codenhub/styles/native` | `dist/native.css` |
28
+ | `@codenhub/styles/palette` | `dist/palette.css` |
29
+ | `@codenhub/styles/aesthetics` | `dist/aesthetics/index.css` |
30
+ | `@codenhub/styles/aesthetics/*` | `dist/aesthetics/<name>.css`, such as `dist/aesthetics/pixel.css` |
31
+
32
+ Link one base file, not several, since they overlap, and any aesthetics you use. Their order does not matter, because every file declares the [cascade layers](../setup.md#cascade-layers) before using one. [Setup → All entrypoints](../setup.md#all-entrypoints) explains what each one contains.
33
+
34
+ ## From a CDN
35
+
36
+ jsDelivr and unpkg serve every file of every published npm version, so a page can link one with nothing installed:
37
+
38
+ ```html
39
+ <head>
40
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codenhub/styles@0.8.0/dist/index.css" />
41
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codenhub/styles@0.8.0/dist/aesthetics/pixel.css" />
42
+ </head>
43
+ ```
44
+
45
+ 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).
46
+
47
+ ## From your own server
48
+
49
+ Install the package, then serve its `dist/` folder as static files:
50
+
51
+ ```sh
52
+ npm install @codenhub/styles
53
+ ```
54
+
55
+ 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.
56
+
57
+ ### Plain HTML
58
+
59
+ Copy `node_modules/@codenhub/styles/dist` into the folder your server publishes, then link it:
60
+
61
+ ```html
62
+ <link rel="stylesheet" href="/vendor/codenhub-styles/index.css" />
63
+ ```
64
+
65
+ Repeat the copy after each upgrade, for example from an npm `postinstall` script.
66
+
67
+ ### Ruby on Rails
68
+
69
+ 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).
70
+
71
+ With Propshaft and no CSS bundler, add the package's folder to the asset paths:
72
+
73
+ ```ruby
74
+ # config/initializers/assets.rb
75
+ Rails.application.config.assets.paths << Rails.root.join("node_modules/@codenhub")
76
+ ```
77
+
78
+ Then link it from the layout, by its path below that folder:
79
+
80
+ ```erb
81
+ <%# app/views/layouts/application.html.erb %>
82
+ <%= stylesheet_link_tag "styles/dist/index" %>
83
+ <%= stylesheet_link_tag "styles/dist/aesthetics/pixel" %>
84
+ ```
85
+
86
+ 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.
87
+
88
+ The files you link are in `dist/`, which holds only finished CSS, plus an empty `index.d.ts` for TypeScript. The Tailwind source lives in `tw/`, outside `dist/`, so a static pipeline that serves or fingerprints `dist/` meets no `@import` it cannot resolve.
89
+
90
+ ### Django
91
+
92
+ Add the folder to `STATICFILES_DIRS` under a prefix, which keeps its file names apart from your own static files:
93
+
94
+ ```python
95
+ # settings.py
96
+ STATICFILES_DIRS = [
97
+ ("codenhub-styles", BASE_DIR / "node_modules/@codenhub/styles/dist"),
98
+ ]
99
+ ```
100
+
101
+ ```django
102
+ {% load static %}
103
+ <link rel="stylesheet" href="{% static 'codenhub-styles/index.css' %}" />
104
+ ```
105
+
106
+ Point the prefix at `dist`, not at the package folder. `dist/` holds only finished CSS, plus an empty `index.d.ts` for TypeScript that the storage copies as it is, so `collectstatic` also works with `ManifestStaticFilesStorage`, which fingerprints each file and rewrites the references inside it. The package folder also holds the Tailwind source in `tw/`, whose `@import "tailwindcss/..."` lines that storage cannot resolve.
107
+
108
+ ### Laravel
109
+
110
+ 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.
111
+
112
+ ## Build only the classes you use
113
+
114
+ The package carries a command, `codenhub-styles`, that compiles it for you. It reads your templates for class names and writes one minified stylesheet with only the StyleKit classes and Tailwind utilities they use. A page that uses one button gets a small fraction of the full stylesheet; the exact size depends on which classes you use, since each component brings the shared rules it relies on.
115
+
116
+ The command works with a bundler too. A project whose bundler does not run Tailwind, such as a plain Vite or webpack build, can write the stylesheet into its sources, `--output src/stylekit.css`, and import that file where it would import `@codenhub/styles`. A project that runs Tailwind CSS v4 gets the same trimming from the [source entrypoint](./tailwind.md) and does not need the command.
117
+
118
+ It needs Node.js 24 or newer on the machine that builds the CSS, whether that is your laptop, a CI job, or a deploy step. It compiles with Tailwind CSS, which the package does not install for you, so a project that only links the compiled stylesheet never downloads it. Install the three packages as development dependencies from your project root; npm creates a `package.json` if you have none, and you need no Tailwind configuration:
119
+
120
+ ```sh
121
+ npm install --save-dev @codenhub/styles @tailwindcss/cli tailwindcss
122
+ ```
123
+
124
+ The stylesheet the command writes is plain CSS, so the servers that serve your site need neither Node.js nor any of these packages. Run it from your project root:
125
+
126
+ ```sh
127
+ npx codenhub-styles build --content "app/views/**/*.erb" --output public/stylekit.css
128
+ ```
129
+
130
+ On success the command prints one line, the absolute path it wrote and the file's size in bytes:
131
+
132
+ ```text
133
+ /home/you/shop/public/stylekit.css 25782 bytes
134
+ ```
135
+
136
+ Link that file from your layout like any static stylesheet.
137
+
138
+ ### Rails views
139
+
140
+ ```sh
141
+ npx codenhub-styles build --content "app/views/**/*.erb" --content "app/helpers/**/*.rb" --output public/stylekit.css
142
+ ```
143
+
144
+ ```erb
145
+ <%# app/views/layouts/application.html.erb %>
146
+ <link rel="stylesheet" href="/stylekit.css" />
147
+ ```
148
+
149
+ ### Laravel Blade views
150
+
151
+ ```sh
152
+ npx codenhub-styles build --content "resources/views/**/*.blade.php" --output public/css/stylekit.css
153
+ ```
154
+
155
+ ```blade
156
+ {{-- resources/views/layouts/app.blade.php --}}
157
+ <link rel="stylesheet" href="{{ asset('css/stylekit.css') }}" />
158
+ ```
159
+
160
+ ### Django templates
161
+
162
+ A Django project keeps templates in a project-level `templates/` folder, in each app's own `templates/` folder, or both. Give one `--content` for each place yours live, and leave out any place you do not use, since a glob that matches nothing fails the build:
163
+
164
+ ```sh
165
+ npx codenhub-styles build --content "templates/**/*.html" --content "shop/templates/**/*.html" --output static/stylekit.css
166
+ ```
167
+
168
+ ```django
169
+ {% load static %}
170
+ <link rel="stylesheet" href="{% static 'stylekit.css' %}" />
171
+ ```
172
+
173
+ Write the output into a folder listed in `STATICFILES_DIRS`, here `static/`, so `collectstatic` picks it up. The settings above list only the package's folder, so add `BASE_DIR / "static"` to that list if your project does not have it yet.
174
+
175
+ ### Options
176
+
177
+ - `--content <glob>`, or `-c <glob>`, names the files to read for class names. It is required and repeatable: pass it once per glob, and the build reads every file any of them matches. A relative glob is resolved against the folder you run the command in, so run it from your project root; an absolute glob is used as given. `**` matches any number of folders, and `{rb,erb}` either extension. Any text file works, whatever its extension. Each glob has to match at least one file, or the build fails and names it, so a typo cannot ship an empty stylesheet. Files your `.gitignore` excludes are still read when a glob matches them, and nothing outside your globs is read.
178
+ - Quote every glob. Without quotes, your shell may expand the glob into a list of files before the command sees it, and only the first file counts as the `--content` value. When that leaves extra file names behind, the build rejects them rather than silently reading less than you meant; when the glob matched a single file, the build reads just that file and nothing your templates add later.
179
+ - `--output <file>`, or `-o <file>`, is the stylesheet to write. It is required. A relative path is resolved against the folder you run the command in, missing parent folders are created, and an existing file is replaced.
180
+ - `--aesthetic <name>` adds one of the [aesthetics](../usage/aesthetics.md): `neobrutalism`, `glass`, `pixel`, `chunky-tile`, `cyber`, or `sketch`. Repeat it for more than one; naming one twice includes it once. Aesthetics are opt-in because the build cannot tell from your templates which one you want, so each is written in full when you ask for it, and none is included when you do not.
181
+ - `--no-minify` writes readable, indented CSS instead. Useful for reading what the build produced; serve the minified file.
182
+ - `--help` prints the usage, with the aesthetics this version ships. `--version` prints the package version. Both build nothing and exit with status 0.
183
+
184
+ The output always holds the theme, its design tokens as CSS custom properties, the reset, and the base rules every component relies on. On top of that come each StyleKit class your templates use, with the variants you combine it with, such as `primary` or `soft`, and each Tailwind utility they use, such as `flex` or `mt-4`. The output is built from the complete stylesheet, not from `/native`, so it has no classless mappings.
185
+
186
+ ### How classes are found
187
+
188
+ The build does not run your templates. It reads each file your `--content` globs match as plain text, collects every word that could be a class name, and writes the rules for the words that are StyleKit classes or Tailwind utilities. This is how Tailwind CSS reads content too.
189
+
190
+ A class has to appear in a file as one whole word. `class="btn primary"`, `class: "btn primary"`, and `classes = ["btn", "primary"]` all work. A word that only looks like a class also counts: a comment that says "card" adds the card's full rules to the stylesheet, which makes the file larger and changes nothing on the page.
191
+
192
+ A class name your code assembles while rendering never appears whole in any file, so the build cannot find it. In `class="btn <%= @order.priority %>"`, `btn` is found, but the intent is whatever `priority` holds at render time; if that is `destructive`, the button renders without its red. Two ways out:
193
+
194
+ - **Write class names whole.** Map each value to a complete class name in a file the build reads, such as `{ "urgent" => "destructive", "normal" => "neutral" }.fetch(@order.priority)` in a helper.
195
+ - **List them in a safelist file.** A plain text file with one class name per line, added with its own `--content`, such as `--content config/stylekit-classes.txt`. Keep it next to the code that builds the class names, so whoever changes one sees the other.
196
+
197
+ ### What it does not do
198
+
199
+ - **No watch mode.** It builds once and exits. Run it again after you change a template, from a script, or from a file watcher your framework or editor already has. A class the stylesheet does not have yet leaves its element unstyled until the next build.
200
+ - **No configuration file and no custom CSS.** You cannot add your own `@theme` values, `@utility` definitions, or plugins. To change the look, override the custom properties in a stylesheet of your own loaded after this one, as [Customizing](../usage/customizing.md) describes. When you need Tailwind's own configuration, install Tailwind CSS and import the source entrypoint from your own Tailwind input, as [Tailwind CSS v4](./tailwind.md) shows.
201
+ - **No other commands.** `build` is the only one; `--help` and `--version` are the only flags that run without it.
202
+ - **No Tailwind version of its own.** Each build uses the `@tailwindcss/cli` and `tailwindcss` installed in your project, within the `>=4.3.2 <5` range StyleKit supports, so your lockfile pins them.
203
+
204
+ ### In a deploy
205
+
206
+ Build the stylesheet before whatever step collects or fingerprints your assets, such as `rails assets:precompile`, `php artisan optimize`, or `python manage.py collectstatic`. Either commit the output, so the servers need no Node.js at all at the cost of a generated file someone has to remember to rebuild, or build it on deploy, so the build machine needs Node.js 24 or newer.
207
+
208
+ Pin the version. Below 1.0 a minor release may rename or remove a class, so the same command can write a different stylesheet with a newer version. Commit `package.json` and the lockfile npm writes, and install with `npm ci` on the build machine, so every build uses the versions you tested.
209
+
210
+ ### When the build fails
211
+
212
+ Every failure prints one line starting with `codenhub-styles:` to standard error and exits with status 1, without writing the output file, so a deploy script stops instead of shipping a stale or empty stylesheet. The line says what went wrong and what to do:
213
+
214
+ - **`missing --content` or `missing --output`.** Add the one it names. An `--output` that is empty or only spaces counts as missing.
215
+ - **`--content "<glob>" matches no file in <folder>`.** Usually a typo in the path, a command run from another folder than your project root, or a glob for a place your project does not use. Building from nothing would write a stylesheet with no component classes, and the site would quietly lose its styling.
216
+ - **`unexpected argument "<file>"`.** Almost always a `--content` glob without quotes, which your shell expanded into a list of files. Quote the glob.
217
+ - **`unknown option "<flag>"`.** A typo, or an option from another tool, such as `--watch` or `--config`. `--help` lists the options.
218
+ - **`option "<flag>" is missing its value or does not take one`.** A flag that takes a value was the last thing on the line, or `--no-minify` was given one, as in `--no-minify=true`.
219
+ - **`unknown aesthetic "<name>"; choose from ...`.** Pick one of the names listed. They are lowercase and hyphenated, as in `chunky-tile`.
220
+ - **`missing command` or `unknown command "<name>"`.** The first word after `codenhub-styles` has to be `build`.
221
+ - **`this command needs @tailwindcss/cli and tailwindcss, which are not installed`.** The line names whichever of the two is missing and ends with the command that installs it. Run that from your project root.
222
+ - **`this command needs Node.js 24 or newer`.** Update Node.js on the machine that builds the CSS.
223
+ - **`Tailwind failed to build the stylesheet: <reason>`.** `<reason>` is Tailwind's own message. `EISDIR` means `--output` names an existing folder, so name a file inside it; `EACCES` or `EPERM` means you cannot write there. For any other reason, run the same command with `--no-minify` to rule out the minifier, and report the message with the version from `--version`.
224
+
225
+ ## Verifying it worked
226
+
227
+ Render one styled element, as in [Integrating → Verifying it worked](./index.md#verifying-it-worked):
228
+
229
+ ```html
230
+ <button class="btn primary">Save changes</button>
231
+ ```
232
+
233
+ 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.
234
+
235
+ ## Next
236
+
237
+ 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.