@usetheo/ui 0.5.0-next.0 → 0.5.1-next.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,75 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.1-next.0] - 2026-05-22
11
+
12
+ Patch — RFC 0008 follow-up. The 0.5.0-next.0 release declared `tailwindcss@^4`
13
+ as a peer dependency and shipped the `./vite-plugin` + `./preset` subpaths,
14
+ but the actual CSS / token / preset artifacts inside the tarball were still
15
+ Tailwind v3 internally. Result: every TheoKit consumer of 0.5.0-next.0 booted
16
+ with unstyled UI in dev and production — `bg-primary`, `text-muted-foreground`,
17
+ `border-border`, `text-body-sm`, etc. emitted as className strings with no
18
+ matching CSS rule.
19
+
20
+ This release rewrites the three v3-shaped artifacts to v4-native syntax and
21
+ ships a fixture-backed real-build dogfood so the regression cannot recur.
22
+
23
+ ### Changed
24
+
25
+ - **`dist/styles.css` is now Tailwind v4 native.** Uses `@import "tailwindcss"`
26
+ (replaces the v3 `@tailwind base; @tailwind components; @tailwind utilities;`
27
+ trio that Tailwind v4 emits as literal strings, with zero utility generation).
28
+ Imports `tokens.css` (runtime cascade) AND `tokens-v4.css` (`@theme` namespace)
29
+ so consumers' Tailwind v4 build resolves both layers correctly. Same
30
+ `@layer base` content (border-color, body font, focus ring, scrollbar
31
+ styling) as before. (#TBD)
32
+ - **`./preset` subpath is now a CSS file.** Tailwind v4 dropped the v3 JS
33
+ preset format — `theme.extend.colors.{name}` declarations are a no-op for
34
+ v4. The new `dist/preset.css` simply chains `@import "./tokens.css"` and
35
+ `@import "./tokens-v4.css"` so consumers can `@import "@usetheo/ui/preset.css"`
36
+ from their own Tailwind v4 entry CSS. (#TBD)
37
+
38
+ ### Added
39
+
40
+ - **`@usetheo/ui/tokens-v4.css` (NEW)** — `@theme {}` block declaring 28
41
+ `--color-*` aliases (full color set), 14 `--text-*` typescale tiers
42
+ (Violet Forge — `--text-display-2xl` through `--text-code-sm` with companion
43
+ `--*--line-height`, `--*--letter-spacing`, `--*--font-weight`), 3 `--font-*`
44
+ family tokens, 7 `--radius-*` tiers, 5 `--shadow-*` levels, 3 `--ease-*`
45
+ timings, and 2 `--animate-*` keyframe-bound utilities. Every color alias
46
+ uses `hsl(var(--*))` indirection so `<ThemeProvider>`'s runtime
47
+ `[data-theme]` cascade keeps working — switching themes still recolors
48
+ every utility. (#TBD)
49
+ - **`@usetheo/ui/styles-v3-legacy.css` (NEW)** — the previous v3-shaped
50
+ `@tailwind base/components/utilities` entry. Pinned consumers on
51
+ `tailwindcss@^3` who still want a prebuilt stylesheet can import this
52
+ subpath. New code SHOULD use `@usetheo/ui/styles.css` (v4) instead.
53
+ - **`@usetheo/ui/preset-v3-legacy` (NEW)** — the v3 JS `Partial<Config>`
54
+ preset that previously lived at `./preset`. Renamed so the canonical
55
+ `./preset` subpath can host the v4 CSS preset. v3 consumers update
56
+ imports from `@usetheo/ui/preset` to `@usetheo/ui/preset-v3-legacy`.
57
+ - **Dogfood scripts** — `pnpm dogfood:v4-zero-config` (shape check, runs in
58
+ `quality:gates`) and `pnpm dogfood:v4-real-build` (end-to-end: packs the
59
+ tarball, installs in a tmp project alongside `@tailwindcss/cli@^4`, runs
60
+ Tailwind v4 against `tests/fixtures/v4-zero-config/`, and grep-asserts the
61
+ expected utility classes appear in the emitted CSS — 12 assertions). The
62
+ real-build dogfood is opt-in (slow, requires network) but catches any
63
+ future regression where v3-shaped artifacts get shipped under a v4 peer
64
+ declaration. (#TBD)
65
+
66
+ ### Notes
67
+
68
+ - **Breaking for any 0.5.0-next.0 consumer.** The `./preset` subpath changed
69
+ from JS (`Partial<Config>` default-export) to CSS file. Code importing
70
+ `import preset from "@usetheo/ui/preset"` will break and must migrate to
71
+ `@import "@usetheo/ui/preset.css"` in an entry CSS. Blast radius: TheoKit
72
+ (already reverted away from 0.5.x by the time this fix shipped) plus any
73
+ community consumer that adopted 0.5.0-next.0 in the same day — likely zero.
74
+ - The runtime indirection via `hsl(var(--*))` aliases keeps `<ThemeProvider>`
75
+ and every built-in theme (`violet-forge`, `dracula`, `vercel-mono`, etc.)
76
+ working with zero changes — the v4 utilities transparently follow the v3
77
+ cascade.
78
+
10
79
  ## [0.5.0-next.0] - 2026-05-22
11
80
 
12
81
  Minor bump — public API gains two subpath exports (`./vite-plugin` and
@@ -0,0 +1,35 @@
1
+ import { Config } from 'tailwindcss';
2
+
3
+ /**
4
+ * `@usetheo/ui/preset-v3-legacy` — Tailwind v3 JS preset (legacy path).
5
+ *
6
+ * Default-export a `Partial<Config>` mirroring the design tokens shipped
7
+ * in `@usetheo/ui/tokens.css`. Adds a `content` field covering the
8
+ * library's published artifact tree so v3-based Tailwind builds emit
9
+ * the utilities used by `@usetheo/ui` components.
10
+ *
11
+ * **Tailwind v4 consumers MUST use `@usetheo/ui/preset.css`**, not this
12
+ * file — Tailwind v4 dropped the JS preset format entirely. This file
13
+ * exists for any remaining `tailwindcss@^3` consumer (notably the
14
+ * shadcn-style copy-paste registry path); new code should not import
15
+ * from this subpath.
16
+ *
17
+ * The token surface is delegated to `./styles/tailwind-preset.ts` (the
18
+ * existing source of truth used by the local Ladle dev surface and the
19
+ * shadcn registry).
20
+ *
21
+ * v3 consumer usage:
22
+ *
23
+ * // tailwind.config.ts (Tailwind v3 only)
24
+ * import preset from "@usetheo/ui/preset-v3-legacy";
25
+ * export default {
26
+ * presets: [preset],
27
+ * content: ["./app/**\/*.{ts,tsx}"],
28
+ * };
29
+ *
30
+ * See RFC 0008 follow-up.
31
+ */
32
+
33
+ declare const preset: Partial<Config>;
34
+
35
+ export { preset as default };
@@ -141,7 +141,7 @@ var theoUIPreset = {
141
141
  plugins: [animate]
142
142
  };
143
143
 
144
- // src/preset.ts
144
+ // src/preset-v3-legacy.ts
145
145
  var LIBRARY_CONTENT_GLOBS = [
146
146
  // Resolved relative to the consumer's `tailwind.config.{ts,js}`.
147
147
  "./node_modules/@usetheo/ui/dist/**/*.{js,mjs,cjs}",
@@ -152,8 +152,8 @@ var preset = {
152
152
  ...theoUIPreset,
153
153
  content: LIBRARY_CONTENT_GLOBS
154
154
  };
155
- var preset_default = preset;
155
+ var preset_v3_legacy_default = preset;
156
156
 
157
- export { preset_default as default };
158
- //# sourceMappingURL=preset.js.map
159
- //# sourceMappingURL=preset.js.map
157
+ export { preset_v3_legacy_default as default };
158
+ //# sourceMappingURL=preset-v3-legacy.js.map
159
+ //# sourceMappingURL=preset-v3-legacy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/styles/tailwind-preset.ts","../src/preset-v3-legacy.ts"],"names":[],"mappings":"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","file":"preset-v3-legacy.js","sourcesContent":["/**\n * Theo UI Tailwind preset — Violet Forge identity.\n *\n * Single source of truth for the design system's utility-level tokens:\n * - colors mapped to CSS variables (HSL split via `hsl(var(--x) / <alpha>)`)\n * - Geist-inspired typescale (display / title / body / label / code tiers)\n * - radii, shadows, motion timing & duration, keyframes\n * - tailwindcss-animate plugin\n *\n * Consumed by:\n * - `tailwind.config.ts` (this repo) via `presets: [theoUIPreset]`\n * - registry/r/tailwind-preset.json (shipped to consumers via shadcn CLI)\n *\n * Consumers integrate as:\n *\n * import type { Config } from \"tailwindcss\";\n * import { theoUIPreset } from \"./styles/tailwind-preset\";\n *\n * export default {\n * darkMode: \"class\",\n * content: [\"./src/**\\/*.{ts,tsx}\"],\n * presets: [theoUIPreset],\n * } satisfies Config;\n *\n * Note: `darkMode` and `content` are NOT in the preset — they are consumer\n * decisions. The preset only contains `theme.extend.*` and `plugins`.\n */\n\nimport type { Config } from \"tailwindcss\";\nimport animate from \"tailwindcss-animate\";\n\nconst hsl = (token: string) => `hsl(var(${token}) / <alpha-value>)`;\n\nexport const theoUIPreset: Partial<Config> = {\n theme: {\n container: {\n center: true,\n padding: \"1rem\",\n screens: {\n \"2xl\": \"1280px\",\n },\n },\n extend: {\n colors: {\n background: hsl(\"--background\"),\n foreground: hsl(\"--foreground\"),\n card: {\n DEFAULT: hsl(\"--card\"),\n foreground: hsl(\"--card-foreground\"),\n },\n popover: {\n DEFAULT: hsl(\"--popover\"),\n foreground: hsl(\"--popover-foreground\"),\n },\n primary: {\n DEFAULT: hsl(\"--primary\"),\n deep: hsl(\"--primary-deep\"),\n glow: hsl(\"--primary-glow\"),\n foreground: hsl(\"--primary-foreground\"),\n },\n secondary: {\n DEFAULT: hsl(\"--secondary\"),\n foreground: hsl(\"--secondary-foreground\"),\n },\n accent: {\n DEFAULT: hsl(\"--accent\"),\n deep: hsl(\"--accent-deep\"),\n foreground: hsl(\"--accent-foreground\"),\n },\n muted: {\n DEFAULT: hsl(\"--muted\"),\n foreground: hsl(\"--muted-foreground\"),\n },\n success: {\n DEFAULT: hsl(\"--success\"),\n foreground: hsl(\"--success-foreground\"),\n },\n warning: {\n DEFAULT: hsl(\"--warning\"),\n foreground: hsl(\"--warning-foreground\"),\n },\n destructive: {\n DEFAULT: hsl(\"--destructive\"),\n foreground: hsl(\"--destructive-foreground\"),\n },\n info: {\n DEFAULT: hsl(\"--info\"),\n foreground: hsl(\"--info-foreground\"),\n },\n border: hsl(\"--border\"),\n input: hsl(\"--input\"),\n ring: hsl(\"--ring\"),\n },\n fontFamily: {\n display: \"var(--font-display)\",\n sans: \"var(--font-body)\",\n mono: \"var(--font-mono)\",\n },\n /* Geist-inspired Violet Forge typescale.\n *\n * Three strict weights: 400 (body), 500 (UI), 600 (display/headings).\n * Letter-spacing scales with size — aggressive negative on display.\n * Mirrors the Vercel/Geist vocabulary while keeping Theo's identity.\n */\n fontSize: {\n // Display tier — aggressive compression, content-led headlines\n \"display-2xl\": [\"64px\", { lineHeight: \"1\", letterSpacing: \"-0.0464em\", fontWeight: \"600\" }],\n \"display-xl\": [\"48px\", { lineHeight: \"1.05\", letterSpacing: \"-0.05em\", fontWeight: \"600\" }],\n \"display-lg\": [\"40px\", { lineHeight: \"1.1\", letterSpacing: \"-0.05em\", fontWeight: \"600\" }],\n \"display-md\": [\"32px\", { lineHeight: \"1.2\", letterSpacing: \"-0.04em\", fontWeight: \"600\" }],\n headline: [\"28px\", { lineHeight: \"1.25\", letterSpacing: \"-0.035em\", fontWeight: \"600\" }],\n // Title tier — section / card heads\n \"title-lg\": [\"24px\", { lineHeight: \"1.33\", letterSpacing: \"-0.04em\", fontWeight: \"600\" }],\n \"title-md\": [\"20px\", { lineHeight: \"1.4\", letterSpacing: \"-0.03em\", fontWeight: \"600\" }],\n // Body tier — FAANG-density realignment 2026-05-22: body-md is the\n // industry-standard 14px (shadcn / Vercel Geist / Linear / Stripe /\n // Mantine). The previous 15px was idiosyncratic. body-sm (14px label\n // weight) remains separate via its line-height / weight signature.\n \"body-lg\": [\"18px\", { lineHeight: \"1.56\", letterSpacing: \"-0.01em\", fontWeight: \"400\" }],\n \"body-md\": [\"14px\", { lineHeight: \"1.43\", letterSpacing: \"0\", fontWeight: \"400\" }],\n \"body-sm\": [\"13px\", { lineHeight: \"1.46\", fontWeight: \"400\" }],\n // Label tier — used on buttons, nav, secondary actions\n label: [\"14px\", { lineHeight: \"1.43\", fontWeight: \"500\" }],\n \"label-caps\": [\"12px\", { lineHeight: \"1.33\", letterSpacing: \"0.04em\", fontWeight: \"500\" }],\n // Mono — code surfaces, technical labels\n \"code-md\": [\"14px\", { lineHeight: \"1.5\", fontWeight: \"400\" }],\n \"code-sm\": [\"13px\", { lineHeight: \"1.54\", fontWeight: \"500\" }],\n },\n borderRadius: {\n none: \"var(--radius-none)\",\n sm: \"var(--radius-sm)\",\n md: \"var(--radius-md)\",\n lg: \"var(--radius-lg)\",\n xl: \"var(--radius-xl)\",\n \"2xl\": \"var(--radius-2xl)\",\n full: \"var(--radius-full)\",\n },\n boxShadow: {\n sm: \"var(--shadow-sm)\",\n md: \"var(--shadow-md)\",\n lg: \"var(--shadow-lg)\",\n glow: \"var(--shadow-glow)\",\n \"glow-strong\": \"var(--shadow-glow-strong)\",\n },\n transitionTimingFunction: {\n \"out-soft\": \"var(--ease-out-soft)\",\n snap: \"var(--ease-snap)\",\n },\n transitionDuration: {\n fast: \"var(--duration-fast)\",\n base: \"var(--duration-base)\",\n slow: \"var(--duration-slow)\",\n },\n keyframes: {\n \"fade-in-up\": {\n \"0%\": { opacity: \"0\", transform: \"translateY(8px)\" },\n \"100%\": { opacity: \"1\", transform: \"translateY(0)\" },\n },\n \"pulse-glow\": {\n \"0%, 100%\": { boxShadow: \"0 0 0 0 hsl(var(--primary) / 0.5)\" },\n \"50%\": { boxShadow: \"0 0 0 8px hsl(var(--primary) / 0)\" },\n },\n },\n animation: {\n \"fade-in-up\": \"fade-in-up var(--duration-base) var(--ease-out-soft) both\",\n \"pulse-glow\": \"pulse-glow 1.5s var(--ease-in-out) infinite\",\n },\n },\n },\n plugins: [animate],\n};\n","/**\n * `@usetheo/ui/preset-v3-legacy` — Tailwind v3 JS preset (legacy path).\n *\n * Default-export a `Partial<Config>` mirroring the design tokens shipped\n * in `@usetheo/ui/tokens.css`. Adds a `content` field covering the\n * library's published artifact tree so v3-based Tailwind builds emit\n * the utilities used by `@usetheo/ui` components.\n *\n * **Tailwind v4 consumers MUST use `@usetheo/ui/preset.css`**, not this\n * file — Tailwind v4 dropped the JS preset format entirely. This file\n * exists for any remaining `tailwindcss@^3` consumer (notably the\n * shadcn-style copy-paste registry path); new code should not import\n * from this subpath.\n *\n * The token surface is delegated to `./styles/tailwind-preset.ts` (the\n * existing source of truth used by the local Ladle dev surface and the\n * shadcn registry).\n *\n * v3 consumer usage:\n *\n * // tailwind.config.ts (Tailwind v3 only)\n * import preset from \"@usetheo/ui/preset-v3-legacy\";\n * export default {\n * presets: [preset],\n * content: [\"./app/**\\/*.{ts,tsx}\"],\n * };\n *\n * See RFC 0008 follow-up.\n */\nimport type { Config } from \"tailwindcss\";\nimport { theoUIPreset } from \"./styles/tailwind-preset.js\";\n\nconst LIBRARY_CONTENT_GLOBS: string[] = [\n // Resolved relative to the consumer's `tailwind.config.{ts,js}`.\n \"./node_modules/@usetheo/ui/dist/**/*.{js,mjs,cjs}\",\n // Yarn PnP / pnpm hoist fallback — Tailwind's globbing tolerates both.\n \"./node_modules/@usetheo/ui/dist/**/*.{ts,tsx}\",\n];\n\nconst preset: Partial<Config> = {\n ...theoUIPreset,\n content: LIBRARY_CONTENT_GLOBS,\n};\n\nexport default preset;\n"]}
@@ -0,0 +1,27 @@
1
+ /* Theo UI — Tailwind v4 CSS preset.
2
+ *
3
+ * For consumers running their own Tailwind v4 build (TheoKit framework
4
+ * path, custom Vite/Astro/Next apps with @tailwindcss/vite, etc.). The
5
+ * preset pulls in:
6
+ * 1. `tokens.css` — runtime `--*` vars `<ThemeProvider>` mutates per
7
+ * theme cascade.
8
+ * 2. `tokens-v4.css` — the `@theme { --color-*, --font-*, --text-*,
9
+ * --radius-*, --shadow-*, --ease-*, --animate-* }` namespace
10
+ * Tailwind v4 actually reads to generate utilities.
11
+ *
12
+ * Consumer usage (their entry CSS):
13
+ *
14
+ * @import "tailwindcss";
15
+ * @import "@usetheo/ui/preset.css";
16
+ *
17
+ * /* the consumer's own @theme overrides come AFTER, so they win. * /
18
+ *
19
+ * Tailwind v4 dropped the v3 JS preset format. The previous JS preset
20
+ * remains shipped under `@usetheo/ui/preset-v3-legacy` (which works only
21
+ * with `tailwindcss@^3`). New v4 consumers MUST use this CSS preset.
22
+ *
23
+ * See RFC 0008 follow-up.
24
+ */
25
+
26
+ @import "./tokens.css";
27
+ @import "./tokens-v4.css";
@@ -0,0 +1,88 @@
1
+ @import "./fonts.css";
2
+ @import "./tokens.css";
3
+
4
+ @tailwind base;
5
+ @tailwind components;
6
+ @tailwind utilities;
7
+
8
+ @layer base {
9
+ * {
10
+ border-color: hsl(var(--border));
11
+ }
12
+
13
+ html {
14
+ font-family: var(--font-body);
15
+ -webkit-font-smoothing: antialiased;
16
+ -moz-osx-font-smoothing: grayscale;
17
+ text-rendering: optimizeLegibility;
18
+ }
19
+
20
+ body {
21
+ background-color: hsl(var(--background));
22
+ color: hsl(var(--foreground));
23
+ /* OpenType ligatures globally — Geist's "liga" feature is structural
24
+ * and gives the Vercel-tight glyph combinations. */
25
+ font-feature-settings: "liga" 1, "ss01" 1;
26
+ }
27
+
28
+ /* Display headings inherit theme display font (Geist by default).
29
+ * Per-size tracking is set in tailwind.config.ts; this is the safety net. */
30
+ h1,
31
+ h2,
32
+ h3,
33
+ h4 {
34
+ font-family: var(--font-display);
35
+ font-weight: 600;
36
+ }
37
+
38
+ /* Code surfaces: use the mono token + tabular numerals so columns of
39
+ * numbers line up in tables/logs/metrics. */
40
+ code,
41
+ pre,
42
+ kbd,
43
+ samp {
44
+ font-family: var(--font-mono);
45
+ font-feature-settings: "tnum" 1, "liga" 1;
46
+ }
47
+
48
+ /* Focus ring — violet (signature) */
49
+ :focus-visible {
50
+ outline: 2px solid hsl(var(--ring));
51
+ outline-offset: 2px;
52
+ }
53
+
54
+ /* Selection — soft violet */
55
+ ::selection {
56
+ background-color: hsl(var(--primary) / 0.25);
57
+ color: hsl(var(--foreground));
58
+ }
59
+
60
+ /* Native scrollbar fallback (Violet Forge).
61
+ * Used for native browser scroll on elements that don't wrap in <ScrollArea>.
62
+ * Components that DO use <ScrollArea> hide the native scrollbar via Radix.
63
+ */
64
+ *::-webkit-scrollbar {
65
+ width: 10px;
66
+ height: 10px;
67
+ }
68
+ *::-webkit-scrollbar-track {
69
+ background: transparent;
70
+ }
71
+ *::-webkit-scrollbar-thumb {
72
+ background-color: hsl(var(--primary) / 0.25);
73
+ border: 2px solid transparent;
74
+ background-clip: content-box;
75
+ border-radius: 9999px;
76
+ transition: background-color var(--duration-fast) var(--ease-out-soft);
77
+ }
78
+ *::-webkit-scrollbar-thumb:hover {
79
+ background-color: hsl(var(--primary) / 0.5);
80
+ }
81
+ *::-webkit-scrollbar-thumb:active {
82
+ background-color: hsl(var(--primary) / 0.75);
83
+ }
84
+ * {
85
+ scrollbar-width: thin;
86
+ scrollbar-color: hsl(var(--primary) / 0.3) transparent;
87
+ }
88
+ }
package/dist/styles.css CHANGED
@@ -1,9 +1,26 @@
1
+ /* Theo UI — Tailwind v4 prebuilt entry stylesheet.
2
+ *
3
+ * What ships at `@usetheo/ui/styles.css` since RFC 0008 follow-up
4
+ * (`0.5.1-next.0`). Consumer imports this once and the framework's
5
+ * Tailwind v4 build picks up:
6
+ * - `@import "tailwindcss"` — Tailwind v4 core (preflight + utilities)
7
+ * - `@import "./fonts.css"` — self-hosted Geist + Geist Mono @font-face
8
+ * - `@import "./tokens.css"` — runtime `--*` vars (theme cascade target)
9
+ * - `@import "./tokens-v4.css"` — `@theme { --color-*, --text-*, … }`
10
+ * namespace Tailwind v4 reads to emit utilities
11
+ * - `@layer base` — `border-color`, body font, focus ring, scrollbar
12
+ * styling that depend on the runtime vars
13
+ *
14
+ * v3-only consumers (Tailwind 3.x + the shadcn registry preset) should
15
+ * load `@usetheo/ui/styles-v3-legacy.css` instead — that file is the
16
+ * unchanged `@tailwind base; @tailwind components; @tailwind utilities`
17
+ * variant. See RFC 0008 follow-up.
18
+ */
19
+
20
+ @import "tailwindcss";
1
21
  @import "./fonts.css";
2
22
  @import "./tokens.css";
3
-
4
- @tailwind base;
5
- @tailwind components;
6
- @tailwind utilities;
23
+ @import "./tokens-v4.css";
7
24
 
8
25
  @layer base {
9
26
  * {
@@ -26,7 +43,7 @@
26
43
  }
27
44
 
28
45
  /* Display headings inherit theme display font (Geist by default).
29
- * Per-size tracking is set in tailwind.config.ts; this is the safety net. */
46
+ * Per-size tracking is set in tokens-v4.css; this is the safety net. */
30
47
  h1,
31
48
  h2,
32
49
  h3,
@@ -0,0 +1,187 @@
1
+ /* Theo UI — Tailwind v4 theme aliases.
2
+ *
3
+ * Companion to `tokens.css`. The base file declares the v3-style runtime
4
+ * variables (`--primary`, `--background`, …) that `<ThemeProvider>` and
5
+ * `[data-theme]` cascades mutate at runtime. This file declares the
6
+ * Tailwind v4 `@theme` namespace (`--color-primary`, `--color-background`,
7
+ * …) by aliasing back to those runtime vars via `hsl(var(--*))`.
8
+ *
9
+ * Why two layers:
10
+ * - `<ThemeProvider>` (and the 10 built-in themes) sets `--primary`
11
+ * etc. at runtime — that's the theme switch surface.
12
+ * - Tailwind v4 resolves color utilities exclusively through
13
+ * `--color-*` tokens declared in `@theme`. Without these aliases
14
+ * `bg-primary`, `text-muted-foreground`, `border-border`, etc. emit
15
+ * a className with no matching CSS rule.
16
+ *
17
+ * The indirection (`--color-primary: hsl(var(--primary))`) preserves the
18
+ * runtime theme cascade — browsers resolve `var(--color-primary)` →
19
+ * `hsl(var(--primary))` → current `[data-theme]` value at paint time.
20
+ *
21
+ * See RFC 0008 follow-up.
22
+ */
23
+
24
+ @theme {
25
+ /* Color tokens ------------------------------------------------------ */
26
+ --color-background: hsl(var(--background));
27
+ --color-foreground: hsl(var(--foreground));
28
+
29
+ --color-card: hsl(var(--card));
30
+ --color-card-foreground: hsl(var(--card-foreground));
31
+
32
+ --color-popover: hsl(var(--popover));
33
+ --color-popover-foreground: hsl(var(--popover-foreground));
34
+
35
+ --color-primary: hsl(var(--primary));
36
+ --color-primary-deep: hsl(var(--primary-deep));
37
+ --color-primary-glow: hsl(var(--primary-glow));
38
+ --color-primary-foreground: hsl(var(--primary-foreground));
39
+
40
+ --color-secondary: hsl(var(--secondary));
41
+ --color-secondary-foreground: hsl(var(--secondary-foreground));
42
+
43
+ --color-accent: hsl(var(--accent));
44
+ --color-accent-deep: hsl(var(--accent-deep));
45
+ --color-accent-foreground: hsl(var(--accent-foreground));
46
+
47
+ --color-muted: hsl(var(--muted));
48
+ --color-muted-foreground: hsl(var(--muted-foreground));
49
+
50
+ --color-border: hsl(var(--border));
51
+ --color-input: hsl(var(--input));
52
+ --color-ring: hsl(var(--ring));
53
+
54
+ --color-success: hsl(var(--success));
55
+ --color-success-foreground: hsl(var(--success-foreground));
56
+ --color-warning: hsl(var(--warning));
57
+ --color-warning-foreground: hsl(var(--warning-foreground));
58
+ --color-destructive: hsl(var(--destructive));
59
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
60
+ --color-info: hsl(var(--info));
61
+ --color-info-foreground: hsl(var(--info-foreground));
62
+
63
+ /* Fonts ------------------------------------------------------------- */
64
+ --font-display: var(--font-display);
65
+ --font-sans: var(--font-body);
66
+ --font-mono: var(--font-mono);
67
+
68
+ /* Violet Forge typescale -------------------------------------------- *
69
+ * Compound text utilities: each `--text-{name}` declares the size,
70
+ * with companion `--*--line-height`, `--*--letter-spacing`, and
71
+ * `--*--font-weight` properties Tailwind v4 picks up automatically.
72
+ */
73
+ --text-display-2xl: 64px;
74
+ --text-display-2xl--line-height: 1;
75
+ --text-display-2xl--letter-spacing: -0.0464em;
76
+ --text-display-2xl--font-weight: 600;
77
+
78
+ --text-display-xl: 48px;
79
+ --text-display-xl--line-height: 1.05;
80
+ --text-display-xl--letter-spacing: -0.05em;
81
+ --text-display-xl--font-weight: 600;
82
+
83
+ --text-display-lg: 40px;
84
+ --text-display-lg--line-height: 1.1;
85
+ --text-display-lg--letter-spacing: -0.05em;
86
+ --text-display-lg--font-weight: 600;
87
+
88
+ --text-display-md: 32px;
89
+ --text-display-md--line-height: 1.2;
90
+ --text-display-md--letter-spacing: -0.04em;
91
+ --text-display-md--font-weight: 600;
92
+
93
+ --text-headline: 28px;
94
+ --text-headline--line-height: 1.25;
95
+ --text-headline--letter-spacing: -0.035em;
96
+ --text-headline--font-weight: 600;
97
+
98
+ --text-title-lg: 24px;
99
+ --text-title-lg--line-height: 1.33;
100
+ --text-title-lg--letter-spacing: -0.04em;
101
+ --text-title-lg--font-weight: 600;
102
+
103
+ --text-title-md: 20px;
104
+ --text-title-md--line-height: 1.4;
105
+ --text-title-md--letter-spacing: -0.03em;
106
+ --text-title-md--font-weight: 600;
107
+
108
+ --text-body-lg: 18px;
109
+ --text-body-lg--line-height: 1.56;
110
+ --text-body-lg--letter-spacing: -0.01em;
111
+ --text-body-lg--font-weight: 400;
112
+
113
+ --text-body-md: 14px;
114
+ --text-body-md--line-height: 1.43;
115
+ --text-body-md--letter-spacing: 0;
116
+ --text-body-md--font-weight: 400;
117
+
118
+ --text-body-sm: 13px;
119
+ --text-body-sm--line-height: 1.46;
120
+ --text-body-sm--font-weight: 400;
121
+
122
+ --text-label: 14px;
123
+ --text-label--line-height: 1.43;
124
+ --text-label--font-weight: 500;
125
+
126
+ --text-label-caps: 12px;
127
+ --text-label-caps--line-height: 1.33;
128
+ --text-label-caps--letter-spacing: 0.04em;
129
+ --text-label-caps--font-weight: 500;
130
+
131
+ --text-code-md: 14px;
132
+ --text-code-md--line-height: 1.5;
133
+ --text-code-md--font-weight: 400;
134
+
135
+ --text-code-sm: 13px;
136
+ --text-code-sm--line-height: 1.54;
137
+ --text-code-sm--font-weight: 500;
138
+
139
+ /* Radii — Tailwind v4 reads the value directly (no var indirection). */
140
+ --radius-none: 0px;
141
+ --radius-sm: 4px;
142
+ --radius-md: 6px;
143
+ --radius-lg: 10px;
144
+ --radius-xl: 14px;
145
+ --radius-2xl: 20px;
146
+ --radius-full: 9999px;
147
+
148
+ /* Shadows — alias to tokens.css computed values (which already use
149
+ * `hsl(var(--foreground) / …)` so theme-switch keeps them in step). */
150
+ --shadow-sm: var(--shadow-sm);
151
+ --shadow-md: var(--shadow-md);
152
+ --shadow-lg: var(--shadow-lg);
153
+ --shadow-glow: var(--shadow-glow);
154
+ --shadow-glow-strong: var(--shadow-glow-strong);
155
+
156
+ /* Motion ------------------------------------------------------------ */
157
+ --ease-out-soft: var(--ease-out-soft);
158
+ --ease-snap: var(--ease-snap);
159
+
160
+ /* Animations — declare so `animate-fade-in-up` and `animate-pulse-glow`
161
+ * resolve. Keyframes are declared below (outside @theme — Tailwind v4
162
+ * picks them up via the @keyframes namespace).
163
+ */
164
+ --animate-fade-in-up: fade-in-up var(--duration-base) var(--ease-out-soft) both;
165
+ --animate-pulse-glow: pulse-glow 1.5s var(--ease-in-out) infinite;
166
+ }
167
+
168
+ @keyframes fade-in-up {
169
+ 0% {
170
+ opacity: 0;
171
+ transform: translateY(8px);
172
+ }
173
+ 100% {
174
+ opacity: 1;
175
+ transform: translateY(0);
176
+ }
177
+ }
178
+
179
+ @keyframes pulse-glow {
180
+ 0%,
181
+ 100% {
182
+ box-shadow: 0 0 0 0 hsl(var(--primary) / 0.5);
183
+ }
184
+ 50% {
185
+ box-shadow: 0 0 0 8px hsl(var(--primary) / 0);
186
+ }
187
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usetheo/ui",
3
- "version": "0.5.0-next.0",
3
+ "version": "0.5.1-next.0",
4
4
  "description": "Theo UI — framework-agnostic React component library with the Violet Forge design system. Focused on AI-agent interfaces, cloud dashboards, and developer-tooling surfaces.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -11,7 +11,11 @@
11
11
  "import": "./dist/index.js"
12
12
  },
13
13
  "./styles.css": "./dist/styles.css",
14
+ "./styles-v3-legacy.css": "./dist/styles-v3-legacy.css",
14
15
  "./tokens.css": "./dist/tokens.css",
16
+ "./tokens-v4.css": "./dist/tokens-v4.css",
17
+ "./preset.css": "./dist/preset.css",
18
+ "./preset": "./dist/preset.css",
15
19
  "./fonts.css": "./dist/fonts.css",
16
20
  "./fonts-cdn.css": "./dist/fonts-cdn.css",
17
21
  "./slide/themes/default.css": "./dist/slide/themes/default.css",
@@ -444,9 +448,9 @@
444
448
  "types": "./dist/vite-plugin.d.ts",
445
449
  "import": "./dist/vite-plugin.js"
446
450
  },
447
- "./preset": {
448
- "types": "./dist/preset.d.ts",
449
- "import": "./dist/preset.js"
451
+ "./preset-v3-legacy": {
452
+ "types": "./dist/preset-v3-legacy.d.ts",
453
+ "import": "./dist/preset-v3-legacy.js"
450
454
  }
451
455
  },
452
456
  "files": ["dist", "registry/r", "registry/index.json", "LICENSE", "CHANGELOG.md"],
@@ -481,7 +485,9 @@
481
485
  "dogfood:slide": "tsx scripts/dogfood-slide.ts",
482
486
  "dogfood:slide-deck": "tsx scripts/dogfood-slide-deck.ts",
483
487
  "dogfood:slide-rich": "tsx scripts/dogfood-slide-rich.ts",
484
- "quality:gates": "pnpm format:check && pnpm lint:ci && pnpm typecheck && pnpm test && pnpm build && pnpm registry:build && pnpm registry:validate && pnpm quality:structure && pnpm quality:bundle && pnpm quality:a11y && pnpm ladle:build && pnpm dogfood:whiteboard && pnpm dogfood:slide && pnpm dogfood:slide-deck && pnpm dogfood:slide-rich",
488
+ "dogfood:v4-zero-config": "tsx scripts/dogfood-v4-zero-config.ts",
489
+ "dogfood:v4-real-build": "bash scripts/dogfood-v4-real-build.sh",
490
+ "quality:gates": "pnpm format:check && pnpm lint:ci && pnpm typecheck && pnpm test && pnpm build && pnpm registry:build && pnpm registry:validate && pnpm quality:structure && pnpm quality:bundle && pnpm quality:a11y && pnpm ladle:build && pnpm dogfood:whiteboard && pnpm dogfood:slide && pnpm dogfood:slide-deck && pnpm dogfood:slide-rich && pnpm dogfood:v4-zero-config",
485
491
  "quality:gates:fast": "pnpm format:check && pnpm lint:ci && pnpm typecheck && pnpm registry:build && pnpm registry:validate && pnpm quality:structure"
486
492
  },
487
493
  "peerDependencies": {
package/dist/preset.d.ts DELETED
@@ -1,31 +0,0 @@
1
- import { Config } from 'tailwindcss';
2
-
3
- /**
4
- * `@usetheo/ui/preset` — Tailwind v4 preset for zero-config consumers.
5
- *
6
- * Default-export a `Partial<Config>` mirroring the design tokens shipped
7
- * in `@usetheo/ui/tokens.css`. Adds a `content` field covering the
8
- * library's published artifact tree so consumers' Tailwind builds emit
9
- * the utilities used by `@usetheo/ui` components.
10
- *
11
- * The token surface is delegated to `./styles/tailwind-preset.ts` (the
12
- * existing source of truth used by the local Ladle dev surface and the
13
- * shadcn registry). This subpath simply wraps it with `content` and
14
- * preserves the same shape, so the v3 registry preset and the v4 import
15
- * preset stay byte-for-byte aligned and impossible to drift.
16
- *
17
- * Consumer usage:
18
- *
19
- * // tailwind.config.ts
20
- * import preset from "@usetheo/ui/preset";
21
- * export default {
22
- * presets: [preset],
23
- * content: ["./app/**\/*.{ts,tsx}"],
24
- * };
25
- *
26
- * See RFC 0008.
27
- */
28
-
29
- declare const preset: Partial<Config>;
30
-
31
- export { preset as default };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/styles/tailwind-preset.ts","../src/preset.ts"],"names":[],"mappings":"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","file":"preset.js","sourcesContent":["/**\n * Theo UI Tailwind preset — Violet Forge identity.\n *\n * Single source of truth for the design system's utility-level tokens:\n * - colors mapped to CSS variables (HSL split via `hsl(var(--x) / <alpha>)`)\n * - Geist-inspired typescale (display / title / body / label / code tiers)\n * - radii, shadows, motion timing & duration, keyframes\n * - tailwindcss-animate plugin\n *\n * Consumed by:\n * - `tailwind.config.ts` (this repo) via `presets: [theoUIPreset]`\n * - registry/r/tailwind-preset.json (shipped to consumers via shadcn CLI)\n *\n * Consumers integrate as:\n *\n * import type { Config } from \"tailwindcss\";\n * import { theoUIPreset } from \"./styles/tailwind-preset\";\n *\n * export default {\n * darkMode: \"class\",\n * content: [\"./src/**\\/*.{ts,tsx}\"],\n * presets: [theoUIPreset],\n * } satisfies Config;\n *\n * Note: `darkMode` and `content` are NOT in the preset — they are consumer\n * decisions. The preset only contains `theme.extend.*` and `plugins`.\n */\n\nimport type { Config } from \"tailwindcss\";\nimport animate from \"tailwindcss-animate\";\n\nconst hsl = (token: string) => `hsl(var(${token}) / <alpha-value>)`;\n\nexport const theoUIPreset: Partial<Config> = {\n theme: {\n container: {\n center: true,\n padding: \"1rem\",\n screens: {\n \"2xl\": \"1280px\",\n },\n },\n extend: {\n colors: {\n background: hsl(\"--background\"),\n foreground: hsl(\"--foreground\"),\n card: {\n DEFAULT: hsl(\"--card\"),\n foreground: hsl(\"--card-foreground\"),\n },\n popover: {\n DEFAULT: hsl(\"--popover\"),\n foreground: hsl(\"--popover-foreground\"),\n },\n primary: {\n DEFAULT: hsl(\"--primary\"),\n deep: hsl(\"--primary-deep\"),\n glow: hsl(\"--primary-glow\"),\n foreground: hsl(\"--primary-foreground\"),\n },\n secondary: {\n DEFAULT: hsl(\"--secondary\"),\n foreground: hsl(\"--secondary-foreground\"),\n },\n accent: {\n DEFAULT: hsl(\"--accent\"),\n deep: hsl(\"--accent-deep\"),\n foreground: hsl(\"--accent-foreground\"),\n },\n muted: {\n DEFAULT: hsl(\"--muted\"),\n foreground: hsl(\"--muted-foreground\"),\n },\n success: {\n DEFAULT: hsl(\"--success\"),\n foreground: hsl(\"--success-foreground\"),\n },\n warning: {\n DEFAULT: hsl(\"--warning\"),\n foreground: hsl(\"--warning-foreground\"),\n },\n destructive: {\n DEFAULT: hsl(\"--destructive\"),\n foreground: hsl(\"--destructive-foreground\"),\n },\n info: {\n DEFAULT: hsl(\"--info\"),\n foreground: hsl(\"--info-foreground\"),\n },\n border: hsl(\"--border\"),\n input: hsl(\"--input\"),\n ring: hsl(\"--ring\"),\n },\n fontFamily: {\n display: \"var(--font-display)\",\n sans: \"var(--font-body)\",\n mono: \"var(--font-mono)\",\n },\n /* Geist-inspired Violet Forge typescale.\n *\n * Three strict weights: 400 (body), 500 (UI), 600 (display/headings).\n * Letter-spacing scales with size — aggressive negative on display.\n * Mirrors the Vercel/Geist vocabulary while keeping Theo's identity.\n */\n fontSize: {\n // Display tier — aggressive compression, content-led headlines\n \"display-2xl\": [\"64px\", { lineHeight: \"1\", letterSpacing: \"-0.0464em\", fontWeight: \"600\" }],\n \"display-xl\": [\"48px\", { lineHeight: \"1.05\", letterSpacing: \"-0.05em\", fontWeight: \"600\" }],\n \"display-lg\": [\"40px\", { lineHeight: \"1.1\", letterSpacing: \"-0.05em\", fontWeight: \"600\" }],\n \"display-md\": [\"32px\", { lineHeight: \"1.2\", letterSpacing: \"-0.04em\", fontWeight: \"600\" }],\n headline: [\"28px\", { lineHeight: \"1.25\", letterSpacing: \"-0.035em\", fontWeight: \"600\" }],\n // Title tier — section / card heads\n \"title-lg\": [\"24px\", { lineHeight: \"1.33\", letterSpacing: \"-0.04em\", fontWeight: \"600\" }],\n \"title-md\": [\"20px\", { lineHeight: \"1.4\", letterSpacing: \"-0.03em\", fontWeight: \"600\" }],\n // Body tier — FAANG-density realignment 2026-05-22: body-md is the\n // industry-standard 14px (shadcn / Vercel Geist / Linear / Stripe /\n // Mantine). The previous 15px was idiosyncratic. body-sm (14px label\n // weight) remains separate via its line-height / weight signature.\n \"body-lg\": [\"18px\", { lineHeight: \"1.56\", letterSpacing: \"-0.01em\", fontWeight: \"400\" }],\n \"body-md\": [\"14px\", { lineHeight: \"1.43\", letterSpacing: \"0\", fontWeight: \"400\" }],\n \"body-sm\": [\"13px\", { lineHeight: \"1.46\", fontWeight: \"400\" }],\n // Label tier — used on buttons, nav, secondary actions\n label: [\"14px\", { lineHeight: \"1.43\", fontWeight: \"500\" }],\n \"label-caps\": [\"12px\", { lineHeight: \"1.33\", letterSpacing: \"0.04em\", fontWeight: \"500\" }],\n // Mono — code surfaces, technical labels\n \"code-md\": [\"14px\", { lineHeight: \"1.5\", fontWeight: \"400\" }],\n \"code-sm\": [\"13px\", { lineHeight: \"1.54\", fontWeight: \"500\" }],\n },\n borderRadius: {\n none: \"var(--radius-none)\",\n sm: \"var(--radius-sm)\",\n md: \"var(--radius-md)\",\n lg: \"var(--radius-lg)\",\n xl: \"var(--radius-xl)\",\n \"2xl\": \"var(--radius-2xl)\",\n full: \"var(--radius-full)\",\n },\n boxShadow: {\n sm: \"var(--shadow-sm)\",\n md: \"var(--shadow-md)\",\n lg: \"var(--shadow-lg)\",\n glow: \"var(--shadow-glow)\",\n \"glow-strong\": \"var(--shadow-glow-strong)\",\n },\n transitionTimingFunction: {\n \"out-soft\": \"var(--ease-out-soft)\",\n snap: \"var(--ease-snap)\",\n },\n transitionDuration: {\n fast: \"var(--duration-fast)\",\n base: \"var(--duration-base)\",\n slow: \"var(--duration-slow)\",\n },\n keyframes: {\n \"fade-in-up\": {\n \"0%\": { opacity: \"0\", transform: \"translateY(8px)\" },\n \"100%\": { opacity: \"1\", transform: \"translateY(0)\" },\n },\n \"pulse-glow\": {\n \"0%, 100%\": { boxShadow: \"0 0 0 0 hsl(var(--primary) / 0.5)\" },\n \"50%\": { boxShadow: \"0 0 0 8px hsl(var(--primary) / 0)\" },\n },\n },\n animation: {\n \"fade-in-up\": \"fade-in-up var(--duration-base) var(--ease-out-soft) both\",\n \"pulse-glow\": \"pulse-glow 1.5s var(--ease-in-out) infinite\",\n },\n },\n },\n plugins: [animate],\n};\n","/**\n * `@usetheo/ui/preset` — Tailwind v4 preset for zero-config consumers.\n *\n * Default-export a `Partial<Config>` mirroring the design tokens shipped\n * in `@usetheo/ui/tokens.css`. Adds a `content` field covering the\n * library's published artifact tree so consumers' Tailwind builds emit\n * the utilities used by `@usetheo/ui` components.\n *\n * The token surface is delegated to `./styles/tailwind-preset.ts` (the\n * existing source of truth used by the local Ladle dev surface and the\n * shadcn registry). This subpath simply wraps it with `content` and\n * preserves the same shape, so the v3 registry preset and the v4 import\n * preset stay byte-for-byte aligned and impossible to drift.\n *\n * Consumer usage:\n *\n * // tailwind.config.ts\n * import preset from \"@usetheo/ui/preset\";\n * export default {\n * presets: [preset],\n * content: [\"./app/**\\/*.{ts,tsx}\"],\n * };\n *\n * See RFC 0008.\n */\nimport type { Config } from \"tailwindcss\";\nimport { theoUIPreset } from \"./styles/tailwind-preset.js\";\n\nconst LIBRARY_CONTENT_GLOBS: string[] = [\n // Resolved relative to the consumer's `tailwind.config.{ts,js}`.\n \"./node_modules/@usetheo/ui/dist/**/*.{js,mjs,cjs}\",\n // Yarn PnP / pnpm hoist fallback — Tailwind's globbing tolerates both.\n \"./node_modules/@usetheo/ui/dist/**/*.{ts,tsx}\",\n];\n\nconst preset: Partial<Config> = {\n ...theoUIPreset,\n content: LIBRARY_CONTENT_GLOBS,\n};\n\nexport default preset;\n"]}