@glasshome/ui 0.5.4 → 1.0.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 (75) hide show
  1. package/README.md +59 -25
  2. package/dist/index.d.ts +10 -3
  3. package/dist/index.js +9 -9
  4. package/dist/lib/alert-tones.d.ts +18 -0
  5. package/dist/lib/badge-tone.d.ts +2 -0
  6. package/dist/lib/button-variants.d.ts +6 -16
  7. package/dist/lib/card-classes.d.ts +19 -0
  8. package/dist/lib/glass-tone.d.ts +2 -0
  9. package/dist/lib/input-classes.d.ts +2 -0
  10. package/dist/lib/logo-lockup.d.ts +38 -0
  11. package/dist/lib/overlay-classes.d.ts +2 -0
  12. package/dist/lib/section-tokens.d.ts +4 -0
  13. package/dist/lib/tier-badge.d.ts +13 -0
  14. package/dist/solid/alert-dialog.d.ts +1 -3
  15. package/dist/solid/alert.d.ts +2 -11
  16. package/dist/solid/badge.d.ts +11 -46
  17. package/dist/solid/bottom-sheet/bottom-sheet.d.ts +1 -1
  18. package/dist/solid/bottom-sheet/constants.d.ts +0 -1
  19. package/dist/solid/bottom-sheet/drag-controller.d.ts +1 -1
  20. package/dist/solid/bottom-sheet/index.d.ts +1 -2
  21. package/dist/solid/breadcrumb.d.ts +1 -1
  22. package/dist/solid/button-group.d.ts +2 -2
  23. package/dist/solid/button.d.ts +1 -1
  24. package/dist/solid/card.d.ts +10 -2
  25. package/dist/solid/carousel.d.ts +1 -1
  26. package/dist/solid/charts.d.ts +45 -0
  27. package/dist/solid/count-pill.d.ts +10 -0
  28. package/dist/solid/data-table.d.ts +66 -0
  29. package/dist/solid/dock.d.ts +3 -0
  30. package/dist/solid/entity-data.d.ts +52 -0
  31. package/dist/solid/field.d.ts +1 -1
  32. package/dist/solid/form.d.ts +1 -1
  33. package/dist/solid/index.d.ts +74 -64
  34. package/dist/solid/index.js +11050 -10848
  35. package/dist/solid/input-group.d.ts +1 -1
  36. package/dist/solid/item.d.ts +3 -2
  37. package/dist/solid/logo.d.ts +23 -0
  38. package/dist/solid/number-field.d.ts +3 -0
  39. package/dist/solid/overlay.d.ts +3 -0
  40. package/dist/solid/page-header.d.ts +18 -0
  41. package/dist/solid/popover.d.ts +7 -1
  42. package/dist/solid/scope-indicator.d.ts +8 -0
  43. package/dist/solid/section-card.d.ts +54 -0
  44. package/dist/solid/select.d.ts +1 -18
  45. package/dist/solid/settings-row.d.ts +34 -0
  46. package/dist/solid/sliding-indicator.d.ts +32 -0
  47. package/dist/solid/sonner.d.ts +35 -4
  48. package/dist/solid/spinner.d.ts +2 -1
  49. package/dist/solid/switch.d.ts +1 -1
  50. package/dist/solid/toggle-group.d.ts +1 -1
  51. package/dist/solid/widget-card.d.ts +29 -0
  52. package/dist/solid/widget-identity.d.ts +47 -0
  53. package/dist/solid/widget-trust-badge.d.ts +16 -0
  54. package/dist/tokens/index.d.ts +3 -3
  55. package/dist/tokens/index.js +11 -11
  56. package/dist/tokens/presets.d.ts +1 -1
  57. package/dist/{utils-JJqwPy_d.js → utils-gbdcvo14.js} +598 -506
  58. package/package.json +38 -17
  59. package/scripts/check-tokens.ts +60 -0
  60. package/scripts/check-ui-drift.mjs +116 -0
  61. package/src/astro/Alert.astro +63 -0
  62. package/src/astro/Badge.astro +16 -0
  63. package/src/astro/Button.astro +43 -0
  64. package/src/astro/Card.astro +39 -0
  65. package/src/astro/Logo.astro +69 -0
  66. package/src/astro/TierBadge.astro +33 -0
  67. package/src/styles/globals.css +157 -0
  68. package/src/styles/theme.css +68 -12
  69. package/dist/solid/calendar.d.ts +0 -17
  70. package/dist/solid/command.d.ts +0 -24
  71. package/dist/solid/drawer.d.ts +0 -22
  72. package/dist/solid/glass-effect.d.ts +0 -6
  73. package/dist/solid/menubar.d.ts +0 -25
  74. package/dist/solid/navigation-menu.d.ts +0 -19
  75. package/dist/solid/sidebar.d.ts +0 -108
package/README.md CHANGED
@@ -2,37 +2,43 @@
2
2
 
3
3
  SolidJS component library for GlassHome, built on [Kobalte](https://kobalte.dev).
4
4
 
5
- 56 accessible, theme-aware components plus utility functions and a Tailwind v4 CSS preset everything you need to build smart-home dashboards. Powers [GlassHome](https://glasshome.app), the local-first dashboard for Home Assistant.
5
+ 70+ accessible, theme-aware components plus framework-agnostic design tokens and a Tailwind v4 CSS preset, everything you need to build smart-home dashboards. Powers [GlassHome](https://glasshome.app), the local-first dashboard for Home Assistant.
6
+
7
+ The whole library wears a single glass material (`.glass` with typed `--glass-*` knobs). `SPEC.md` is the design-system contract; the live gallery (`bun run dev:gallery`) is its executable form.
6
8
 
7
9
  ## Install
8
10
 
9
11
  ```bash
10
- npm install @glasshome/ui solid-js
12
+ bun add @glasshome/ui solid-js @glasshome/sync-layer
11
13
  # or
12
- bun add @glasshome/ui solid-js
14
+ npm install @glasshome/ui solid-js @glasshome/sync-layer
13
15
  ```
14
16
 
15
- > `solid-js ^1.9.9` is a required peer dependency.
17
+ Peer dependencies:
16
18
 
17
- ## Subpath Imports
19
+ | Package | Needed for |
20
+ | --- | --- |
21
+ | `solid-js` `^1.9` | everything under `/solid` |
22
+ | `@glasshome/sync-layer` | `/solid` only (EntitySelector, AreaPicker, demo-mode helpers) |
18
23
 
19
- ### `@glasshome/ui` Utilities
24
+ The package is **ESM-only** and ships modern ESM with type declarations that resolve under both bundler and Node 16+ module resolution. Node `>=20`.
20
25
 
21
- Framework-agnostic helpers exported from the root entrypoint.
26
+ ## Entry points
22
27
 
23
- ```typescript
24
- import { cn, createIsMobile } from "@glasshome/ui";
28
+ ### `@glasshome/ui` — utilities and surface recipes
25
29
 
26
- // Merge Tailwind classes with conflict resolution
27
- const cls = cn("px-4 py-2", condition && "bg-primary text-white");
30
+ Framework-agnostic root: class-string recipes for the sanctioned glass surfaces, safe to import from server code (e.g. Astro frontmatter) where Solid components cannot run.
28
31
 
29
- // Reactive mobile breakpoint signal (SolidJS)
30
- const isMobile = createIsMobile();
32
+ ```typescript
33
+ import { cn, buttonVariants, CARD_SURFACE, ALERT_TONES, OVERLAY_SURFACE } from "@glasshome/ui";
34
+
35
+ const cls = cn("px-4 py-2", condition && "text-white");
36
+ const btn = buttonVariants({ variant: "outline", size: "sm" });
31
37
  ```
32
38
 
33
- ### `@glasshome/ui/solid` — Components
39
+ ### `@glasshome/ui/solid` — components
34
40
 
35
- All 56 Kobalte-based components are exported from a single subpath.
41
+ All components are exported from a single subpath.
36
42
 
37
43
  ```tsx
38
44
  import { Button, Card, CardHeader, CardTitle, CardContent, Badge } from "@glasshome/ui/solid";
@@ -42,7 +48,7 @@ function DeviceCard() {
42
48
  <Card>
43
49
  <CardHeader>
44
50
  <CardTitle>Living Room</CardTitle>
45
- <Badge>Online</Badge>
51
+ <Badge tone="var(--success)" dot>Online</Badge>
46
52
  </CardHeader>
47
53
  <CardContent>
48
54
  <Button onClick={() => console.log("toggled")}>Toggle Light</Button>
@@ -52,25 +58,53 @@ function DeviceCard() {
52
58
  }
53
59
  ```
54
60
 
55
- Available components include:
61
+ Component families: `Accordion` · `Alert` · `AlertDialog` · `AreaPicker` · `AspectRatio` · `Avatar` · `Badge` · `BottomSheet` · `Breadcrumb` · `Button` · `ButtonGroup` · `Calendar` · `Card` · `Carousel` · `Charts (AreaChart, BarList)` · `Checkbox` · `Collapsible` · `ColorSlider` · `ColorWheel` · `Command` · `ContextMenu` · `CopyButton` · `CountPill` · `DataTable` · `Dialog` · `Dock` · `DropdownMenu` · `Empty` · `EntitySelector` · `Field` · `Form` · `HoverCard` · `Input` · `InputGroup` · `InputOTP` · `Item` · `Kbd` · `Label` · `Logo` · `Menubar` · `NavigationMenu` · `NumberField` · `Overlay` · `PageHeader` · `Pagination` · `Popover` · `Progress` · `RadioGroup` · `Resizable` · `ResponsiveDialog` · `SchemaForm` · `ScopeIndicator` · `ScrollArea` · `SectionCard` · `Select` · `Separator` · `SettingsRow` · `Sheet` · `Sidebar` · `Skeleton` · `Slider` · `SlidingIndicator` · `Sonner (toast)` · `Spinner` · `Switch` · `Table` · `Tabs` · `Textarea` · `TierBadge` · `Toggle` · `ToggleGroup` · `Tooltip` · `WidgetCard` · `WidgetIdentity` · `WidgetTrustBadge`
56
62
 
57
- `Accordion` · `Alert` · `AlertDialog` · `AspectRatio` · `Avatar` · `Badge` · `Breadcrumb` · `Button` · `ButtonGroup` · `Calendar` · `Card` · `Carousel` · `Checkbox` · `Collapsible` · `Command` · `ContextMenu` · `CopyButton` · `Dialog` · `Dock` · `Drawer` · `DropdownMenu` · `Empty` · `Field` · `Form` · `GeometricBackground` · `GlassEffect` · `HoverCard` · `Input` · `InputGroup` · `InputOTP` · `Item` · `Kbd` · `Label` · `Menubar` · `NavigationMenu` · `Pagination` · `Popover` · `Progress` · `RadioGroup` · `ResizablePanel` · `ResponsiveDialog` · `ScrollArea` · `Select` · `Separator` · `Sheet` · `Skeleton` · `Slider` · `Sonner (toast)` · `Spinner` · `Switch` · `Table` · `Tabs` · `Textarea` · `Toggle` · `ToggleGroup` · `Tooltip`
63
+ `Badge` is glass-only: `tone` takes any CSS color (`<Badge tone="var(--success)" dot>`); there are no solid variant badges.
58
64
 
59
- ### `@glasshome/ui/styles` — Tailwind v4 CSS
65
+ ### `@glasshome/ui/tokens` — design tokens as data
66
+
67
+ Framework-free theme model: presets, oklch parsing/derivation, and oklch→hex conversion (gamut-mapped, for renderers that cannot parse oklch). Safe in Node scripts, servers, and build tooling.
68
+
69
+ ```typescript
70
+ import { THEME_PRESETS, DEFAULT_THEME_ID, resolveThemeColors, oklchToHex } from "@glasshome/ui/tokens";
71
+ ```
60
72
 
61
- Import the shared CSS preset in your app's stylesheet:
73
+ ### `@glasshome/ui/astro/*` zero-JS server components
74
+
75
+ Astro components rendering the same surfaces with no client JS:
76
+
77
+ ```astro
78
+ ---
79
+ import Badge from "@glasshome/ui/astro/Badge.astro";
80
+ import Button from "@glasshome/ui/astro/Button.astro";
81
+ import Card from "@glasshome/ui/astro/Card.astro";
82
+ import Alert from "@glasshome/ui/astro/Alert.astro";
83
+ ---
84
+ ```
85
+
86
+ Do not import `@glasshome/ui/solid` in server-run `.astro` files; use these or the root recipes instead.
87
+
88
+ ### `@glasshome/ui/styles` — Tailwind v4 CSS
62
89
 
63
90
  ```css
64
91
  @import "@glasshome/ui/styles";
65
92
  ```
66
93
 
67
- This provides the GlassHome design tokens (colors, radii, animations) as a Tailwind v4 theme layer.
94
+ Provides the glass material, design tokens (colors, radii, animations), and the Tailwind v4 theme layer. `@glasshome/ui/styles/theme` exposes the token palette alone.
68
95
 
69
- ## Peer Dependencies
96
+ ## Development
70
97
 
71
- | Package | Required | Notes |
72
- | ---------- | -------- | ---------------------------------------- |
73
- | `solid-js` | Yes | SolidJS reactive primitives and JSX runtime |
98
+ ```bash
99
+ bun install
100
+ bun run dev:gallery # live component gallery on :5199, hot-reloads against src
101
+ bun run test # vitest unit + render smoke tests
102
+ bun run lint # biome
103
+ bun run check:tokens # theme.css <-> tokens/presets.ts sync guard
104
+ bun run check:types # typecheck src + tests
105
+ bun run build # dist ESM + declarations
106
+ bun run check:publish # publint + arethetypeswrong
107
+ ```
74
108
 
75
109
  ## License
76
110
 
package/dist/index.d.ts CHANGED
@@ -1,3 +1,10 @@
1
- export { buttonVariants } from "./lib/button-variants";
2
- export { createIsMobile } from "./lib/use-is-mobile";
3
- export { cn } from "./lib/utils";
1
+ export { ALERT_CLASS, ALERT_CONTENT_CLASS, ALERT_DESCRIPTION_CLASS, ALERT_ICON_BG_CLASS, ALERT_ICON_CLASS, ALERT_ICON_PATHS, ALERT_TITLE_CLASS, ALERT_TONES, type AlertTone, type AlertToneStyle, alertBorder, alertFill, alertIconBgStyle, alertIconFill, } from "./lib/alert-tones.js";
2
+ export { BUTTON_DEFAULT_CLASS, BUTTON_OUTLINE_CLASS, buttonVariants, ICON_BUTTON_CLASS, } from "./lib/button-variants.js";
3
+ export { CARD_BLUR, CARD_SURFACE, CARD_SURFACE_BASE, CARD_SURFACE_OPAQUE, TRACK_SURFACE, } from "./lib/card-classes.js";
4
+ export { glassToneText, toneTextMix } from "./lib/glass-tone.js";
5
+ export { INPUT_CLASS, INPUT_SURFACE } from "./lib/input-classes.js";
6
+ export { LOGO_DEFAULT_SIZE, LOGO_DEFAULT_SRC, LOGO_DEFAULT_SUB, LOGO_MARK_CLASS, LOGO_MARK_PX, LOGO_NAME_CLASS, LOGO_ROOT_CLASS, LOGO_SIZES, LOGO_STACK_CLASS, LOGO_SUB_CLASS, type LogoSize, } from "./lib/logo-lockup.js";
7
+ export { OVERLAY_SURFACE, SCRIM_CLASS } from "./lib/overlay-classes.js";
8
+ export { SECTION_INNER_RADIUS, SECTION_OUTER_RADIUS, SECTION_PADDING, SECTION_ROW_CLASS, } from "./lib/section-tokens.js";
9
+ export { createIsMobile } from "./lib/use-is-mobile.js";
10
+ export { cn } from "./lib/utils.js";
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
- import { n as e, t } from "./utils-JJqwPy_d.js";
2
- import { createSignal as n, onCleanup as r, onMount as i } from "solid-js";
1
+ import { A as e, B as t, C as n, F as r, G as i, H as a, I as o, J as s, K as c, L as l, M as u, P as d, R as f, U as p, V as m, W as h, X as g, Y as _, Z as v, _ as y, a as b, b as x, c as S, d as C, f as w, g as T, h as E, i as D, j as O, l as k, m as A, n as j, o as M, p as N, q as P, r as F, s as I, t as L, u as R, v as z, x as B, y as V } from "./utils-gbdcvo14.js";
2
+ import { createSignal as H, onCleanup as U, onMount as W } from "solid-js";
3
3
  //#region src/lib/use-is-mobile.ts
4
- var a = 768;
5
- function o() {
6
- let [e, t] = n(void 0);
7
- return i(() => {
8
- let e = window.matchMedia(`(max-width: ${a - 1}px)`), n = () => t(window.innerWidth < a);
9
- e.addEventListener("change", n), t(window.innerWidth < a), r(() => e.removeEventListener("change", n));
4
+ var G = 768;
5
+ function K() {
6
+ let [e, t] = H(void 0);
7
+ return W(() => {
8
+ let e = window.matchMedia(`(max-width: ${G - 1}px)`), n = () => t(window.innerWidth < G);
9
+ e.addEventListener("change", n), t(window.innerWidth < G), U(() => e.removeEventListener("change", n));
10
10
  }), e;
11
11
  }
12
12
  //#endregion
13
- export { e as buttonVariants, t as cn, o as createIsMobile };
13
+ export { t as ALERT_CLASS, m as ALERT_CONTENT_CLASS, a as ALERT_DESCRIPTION_CLASS, p as ALERT_ICON_BG_CLASS, h as ALERT_ICON_CLASS, i as ALERT_ICON_PATHS, c as ALERT_TITLE_CLASS, P as ALERT_TONES, r as BUTTON_DEFAULT_CLASS, o as BUTTON_OUTLINE_CLASS, n as CARD_BLUR, e as CARD_SURFACE, O as CARD_SURFACE_BASE, u as CARD_SURFACE_OPAQUE, l as ICON_BUTTON_CLASS, z as INPUT_CLASS, V as INPUT_SURFACE, S as LOGO_DEFAULT_SIZE, k as LOGO_DEFAULT_SRC, R as LOGO_DEFAULT_SUB, C as LOGO_MARK_CLASS, w as LOGO_MARK_PX, N as LOGO_NAME_CLASS, A as LOGO_ROOT_CLASS, E as LOGO_SIZES, T as LOGO_STACK_CLASS, y as LOGO_SUB_CLASS, M as OVERLAY_SURFACE, I as SCRIM_CLASS, j as SECTION_INNER_RADIUS, F as SECTION_OUTER_RADIUS, D as SECTION_PADDING, b as SECTION_ROW_CLASS, d as TRACK_SURFACE, s as alertBorder, _ as alertFill, g as alertIconBgStyle, v as alertIconFill, f as buttonVariants, L as cn, K as createIsMobile, x as glassToneText, B as toneTextMix };
@@ -0,0 +1,18 @@
1
+ export type AlertTone = "info" | "warning" | "success" | "destructive";
2
+ export type AlertToneStyle = {
3
+ color: string;
4
+ icon: string;
5
+ text: string;
6
+ };
7
+ export declare const ALERT_TONES: Record<AlertTone, AlertToneStyle>;
8
+ export declare const ALERT_ICON_PATHS: Record<AlertTone, string>;
9
+ export declare const alertBorder: (c: string) => string;
10
+ export declare const alertFill: (c: string) => string;
11
+ export declare const alertIconFill: (c: string) => string;
12
+ export declare const ALERT_CLASS = "relative overflow-hidden flex items-start gap-3 rounded-lg border p-3 backdrop-blur-sm";
13
+ export declare const ALERT_ICON_CLASS = "flex size-8 shrink-0 items-center justify-center rounded-md [&>svg]:size-[18px]";
14
+ export declare const ALERT_ICON_BG_CLASS = "pointer-events-none absolute -right-3 -bottom-4 [&>svg]:size-28 [&>svg]:[stroke-width:2.5px]";
15
+ export declare function alertIconBgStyle(color: string): Record<string, string>;
16
+ export declare const ALERT_CONTENT_CLASS = "relative z-10 min-w-0 flex-1";
17
+ export declare const ALERT_TITLE_CLASS = "font-semibold text-base leading-snug";
18
+ export declare const ALERT_DESCRIPTION_CLASS = "text-foreground/80 text-sm leading-snug [&:not(:first-child)]:mt-0.5";
@@ -0,0 +1,2 @@
1
+ export declare const BADGE_DEFAULT_TONE = "var(--primary)";
2
+ export declare const BADGE_TONE_CLASS = "inline-flex w-fit shrink-0 cursor-default select-none items-center gap-1.5 whitespace-nowrap rounded-full border px-2.5 py-0.5 font-medium text-xs";
@@ -1,22 +1,11 @@
1
- /**
2
- * Button class recipe. Pure (only `cva`, no Solid/Kobalte), so it can be
3
- * imported server-side and from framework-agnostic entry points — Astro
4
- * frontmatter pulls this to build class strings without hydrating a component.
5
- * The Solid `<Button>` and the hub's marketing pill tokens share this one recipe.
6
- *
7
- * Buttons are pills: `rounded-full` is the base shape everywhere. `size: none`
8
- * is sizeless (color + shape only) for callers that supply their own height and
9
- * padding.
10
- */
11
1
  export declare const buttonVariants: import("cva").CVAComponent<Omit<{
12
2
  base: string;
13
3
  variants: {
14
4
  variant: {
15
5
  default: string;
16
- gradient: string;
17
6
  destructive: string;
18
- outline: string;
19
7
  secondary: string;
8
+ outline: string;
20
9
  ghost: string;
21
10
  link: string;
22
11
  };
@@ -36,10 +25,9 @@ export declare const buttonVariants: import("cva").CVAComponent<Omit<{
36
25
  variants: {
37
26
  variant: {
38
27
  default: string;
39
- gradient: string;
40
28
  destructive: string;
41
- outline: string;
42
29
  secondary: string;
30
+ outline: string;
43
31
  ghost: string;
44
32
  link: string;
45
33
  };
@@ -58,10 +46,9 @@ export declare const buttonVariants: import("cva").CVAComponent<Omit<{
58
46
  }, {
59
47
  variant: {
60
48
  default: string;
61
- gradient: string;
62
49
  destructive: string;
63
- outline: string;
64
50
  secondary: string;
51
+ outline: string;
65
52
  ghost: string;
66
53
  link: string;
67
54
  };
@@ -73,3 +60,6 @@ export declare const buttonVariants: import("cva").CVAComponent<Omit<{
73
60
  none: string;
74
61
  };
75
62
  }>;
63
+ export declare const BUTTON_DEFAULT_CLASS: string;
64
+ export declare const BUTTON_OUTLINE_CLASS: string;
65
+ export declare const ICON_BUTTON_CLASS = "inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full transition-all duration-150 hover:bg-primary/10 active:scale-90";
@@ -0,0 +1,19 @@
1
+ export declare const CARD_SURFACE_BASE = "glass [--glass-wash:20%] [--glass-rim:0.3] [--glass-lift:0.45] [--glass-shade:0.05] dark:[--glass-shade:0] [--glass-base:color-mix(in_srgb,var(--card)_60%,transparent)]";
2
+ export declare const CARD_BLUR = "backdrop-blur-[var(--glass-blur,24px)] backdrop-saturate-[1.8]";
3
+ export declare const CARD_SURFACE = "glass [--glass-wash:20%] [--glass-rim:0.3] [--glass-lift:0.45] [--glass-shade:0.05] dark:[--glass-shade:0] [--glass-base:color-mix(in_srgb,var(--card)_60%,transparent)] backdrop-blur-[var(--glass-blur,24px)] backdrop-saturate-[1.8]";
4
+ export declare const CARD_SURFACE_OPAQUE = "glass [--glass-wash:20%] [--glass-rim:0.3] [--glass-lift:0.45] [--glass-shade:0.05] dark:[--glass-shade:0]";
5
+ export declare const TRACK_SURFACE = "border border-border/50 bg-card/40 backdrop-blur-sm";
6
+ export declare const CARD_PADDING: {
7
+ readonly slots: "flex flex-col gap-3 py-3 md:gap-4 md:py-4";
8
+ readonly md: "p-4";
9
+ readonly sm: "p-3";
10
+ readonly none: "";
11
+ };
12
+ export type CardPadding = keyof typeof CARD_PADDING;
13
+ export declare const CARD_INTERACTIVE = "cursor-pointer transition-colors duration-200 hover:border-border hover:bg-foreground/[0.03] focus-within:border-border";
14
+ export declare const CARD_HEADER_CLASS = "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] md:px-4";
15
+ export declare const CARD_TITLE_CLASS = "font-semibold leading-none";
16
+ export declare const CARD_DESCRIPTION_CLASS = "text-muted-foreground text-sm";
17
+ export declare const CARD_ACTION_CLASS = "col-start-2 row-span-2 row-start-1 self-start justify-self-end";
18
+ export declare const CARD_CONTENT_CLASS = "px-3 md:px-4";
19
+ export declare const CARD_FOOTER_CLASS = "flex items-center px-3 md:px-4 [.border-t]:pt-6";
@@ -0,0 +1,2 @@
1
+ export declare function toneTextMix(color: string): number;
2
+ export declare function glassToneText(color: string): string;
@@ -0,0 +1,2 @@
1
+ export declare const INPUT_SURFACE = "glass glass-sink [--glass-base:var(--input)] [--glass-light:0.04]";
2
+ export declare const INPUT_CLASS = "flex h-9 w-full min-w-0 rounded-md glass glass-sink [--glass-base:var(--input)] [--glass-light:0.04] px-3 py-1 text-base outline-none transition-[color,box-shadow] selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-sm placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40";
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The GlassHome lockup spec, pure — shared by the Solid <Logo>, the Astro
3
+ * <Logo>, and any `.astro` consumer that needs the class strings without
4
+ * hydrating a component.
5
+ *
6
+ * One ratio everywhere (audit L2): the sub-brand line is the dominant element,
7
+ * the wordmark sits above it as a smaller eyebrow. Sub-line spec (audit L1):
8
+ * text-primary, uppercase, bold, tracking-[0.18em] — never restyled per
9
+ * surface, never recolored, and the mark is never stretched or used as an
10
+ * avatar.
11
+ */
12
+ export type LogoSize = "sm" | "md" | "lg";
13
+ export declare const LOGO_DEFAULT_SRC = "/assets/glasshome_logo.png";
14
+ export declare const LOGO_DEFAULT_SUB = "Dash";
15
+ export declare const LOGO_DEFAULT_SIZE: LogoSize;
16
+ /** Rendered pixel size of the mark per size, for width/height attrs (CLS). */
17
+ export declare const LOGO_MARK_PX: Record<LogoSize, number>;
18
+ export declare const LOGO_SIZES: Record<LogoSize, {
19
+ mark: string;
20
+ name: string;
21
+ sub: string;
22
+ gap: string;
23
+ }>;
24
+ /**
25
+ * The stack sits on the mark's baseline (items-end), so the sub-brand line
26
+ * bottoms out level with the mark rather than floating centred against it.
27
+ */
28
+ export declare const LOGO_ROOT_CLASS = "inline-flex items-end";
29
+ /** The two lines are pinned by an explicit gap, never by line-height slack. */
30
+ export declare const LOGO_STACK_CLASS = "flex flex-col gap-0.5";
31
+ /**
32
+ * Compose as cn(SIZE, BASE), not cn(BASE, SIZE): tailwind-merge treats a
33
+ * font-size class as carrying a line-height, so a trailing `text-2xl` would
34
+ * strip the `leading-none` these rely on.
35
+ */
36
+ export declare const LOGO_MARK_CLASS = "shrink-0";
37
+ export declare const LOGO_NAME_CLASS = "whitespace-nowrap font-bold leading-none tracking-tight";
38
+ export declare const LOGO_SUB_CLASS = "font-bold text-primary uppercase leading-none tracking-[0.18em]";
@@ -0,0 +1,2 @@
1
+ export declare const OVERLAY_SURFACE = "glass [--glass-base:var(--popover)] [--glass-rim:0.3] [--glass-lift:0.55]";
2
+ export declare const SCRIM_CLASS = "bg-background/70 backdrop-blur-sm";
@@ -0,0 +1,4 @@
1
+ export declare const SECTION_OUTER_RADIUS = "rounded-[var(--radius)]";
2
+ export declare const SECTION_INNER_RADIUS = "rounded-[max(0px,calc(var(--radius)-0.75rem))]";
3
+ export declare const SECTION_PADDING = "p-3";
4
+ export declare const SECTION_ROW_CLASS = "rounded-[max(0px,calc(var(--radius)-0.75rem))] border border-border/60 bg-card/60 p-3";
@@ -0,0 +1,13 @@
1
+ export declare const TIER_BADGE_CLASS = "inline-flex cursor-default select-none items-center rounded-full px-2 py-0.5 font-black text-[10px] uppercase tracking-wider";
2
+ /** Optional sweep shaping. Default is the symmetric brushed look (both ends
3
+ * `hi`, dipping to `lo` at the midpoint). The collectible/license golds are a
4
+ * lit bevel instead: they dip early and land on a darker `end`. */
5
+ export interface TierSweep {
6
+ /** Far end of the sweep. Default: `hi` (symmetric). */
7
+ end?: string;
8
+ /** Where `lo` sits, in percent. Default: 50. */
9
+ stop?: number;
10
+ }
11
+ /** Inline style for the metallic pill body. Keys are CSS property names (works
12
+ * as a Solid `style` object and, joined, as an Astro `style` string). */
13
+ export declare function tierBadgeStyle(hi: string, lo: string, text: string, sweep?: TierSweep): Record<string, string>;
@@ -10,8 +10,6 @@ declare const AlertDialog: typeof import("@kobalte/core/alert-dialog").Root & {
10
10
  Trigger: typeof import("@kobalte/core/alert-dialog").Trigger;
11
11
  };
12
12
  declare const AlertDialogTrigger: Component<ComponentProps<typeof AlertDialogPrimitive.Trigger>>;
13
- declare const AlertDialogPortal: typeof import("@kobalte/core/alert-dialog").Portal;
14
- declare const AlertDialogOverlay: Component<ComponentProps<typeof AlertDialogPrimitive.Overlay>>;
15
13
  declare const AlertDialogContent: Component<ComponentProps<typeof AlertDialogPrimitive.Content>>;
16
14
  declare const AlertDialogHeader: Component<ComponentProps<"div">>;
17
15
  declare const AlertDialogFooter: Component<ComponentProps<"div">>;
@@ -19,4 +17,4 @@ declare const AlertDialogTitle: Component<ComponentProps<typeof AlertDialogPrimi
19
17
  declare const AlertDialogDescription: Component<ComponentProps<typeof AlertDialogPrimitive.Description>>;
20
18
  declare const AlertDialogAction: Component<ComponentProps<typeof AlertDialogPrimitive.CloseButton>>;
21
19
  declare const AlertDialogCancel: Component<ComponentProps<typeof AlertDialogPrimitive.CloseButton>>;
22
- export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, };
20
+ export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, };
@@ -1,22 +1,13 @@
1
1
  import { type Component, type ComponentProps, type JSX } from "solid-js";
2
- /**
3
- * Tone-driven alert (the design formerly known as hub's SectionAlert). One
4
- * component, four tones, both themes, all color from theme vars via color-mix.
5
- * Text mixes in oklab (not oklch) so a hued tone desaturates toward neutral
6
- * with its hue intact instead of swinging toward yellow.
7
- */
8
- export type AlertTone = "info" | "warning" | "success" | "destructive";
2
+ import { type AlertTone } from "../lib/alert-tones.js";
3
+ export type { AlertTone };
9
4
  type AlertProps = ComponentProps<"div"> & {
10
5
  tone?: AlertTone;
11
- /** Override the default per-tone icon with any JSX (e.g. a lucide-solid icon). */
12
6
  icon?: JSX.Element;
13
- /** Bold heading line. */
14
7
  title?: JSX.Element;
15
- /** Trailing element pinned right (e.g. a Button). */
16
8
  action?: JSX.Element;
17
9
  };
18
10
  declare const Alert: Component<AlertProps>;
19
- /** Back-compat sub-parts for the older compound usage (Alert > AlertTitle/Description). */
20
11
  declare const AlertTitle: Component<ComponentProps<"div">>;
21
12
  declare const AlertDescription: Component<ComponentProps<"div">>;
22
13
  export { Alert, AlertDescription, AlertTitle };
@@ -1,57 +1,22 @@
1
- import { type VariantProps } from "cva";
2
1
  import { type Component, type ComponentProps, type ValidComponent } from "solid-js";
3
- declare const badgeVariants: import("cva").CVAComponent<Omit<{
4
- base: string;
5
- variants: {
6
- variant: {
7
- default: string;
8
- secondary: string;
9
- destructive: string;
10
- outline: string;
11
- };
12
- };
13
- defaultVariants: {
14
- variant: "default";
15
- };
16
- }, "defaultVariants"> & {
17
- variants: {
18
- variant: {
19
- default: string;
20
- secondary: string;
21
- destructive: string;
22
- outline: string;
23
- };
24
- };
25
- defaultVariants: Omit<{}, "variant"> & {
26
- variant: "default";
27
- };
28
- }, {
29
- variant: {
30
- default: string;
31
- secondary: string;
32
- destructive: string;
33
- outline: string;
34
- };
35
- }>;
36
- type BadgeProps = ComponentProps<"span"> & VariantProps<typeof badgeVariants> & {
37
- component?: ValidComponent;
38
- /**
39
- * Glass tone chip: pass any CSS color (a semantic token like var(--success)
40
- * or an arbitrary categorical hue) and the badge renders as a frosted tinted
41
- * pill, both themes, no dark: overrides. Overrides `variant` when set.
42
- */
2
+ type BadgeProps = ComponentProps<"span"> & {
3
+ as?: ValidComponent;
4
+ /** Any CSS color (semantic token or arbitrary hue). Defaults to var(--primary). */
43
5
  tone?: string;
44
- /** With `tone`: render a lit status dot before the label. */
45
- dot?: boolean;
46
6
  };
47
7
  declare const Badge: Component<BadgeProps>;
48
8
  type TierBadgeProps = ComponentProps<"span"> & {
49
- /** Gradient high stop (both ends of the diagonal sweep). */
9
+ /** Gradient high stop (the near end of the diagonal sweep, and by default
10
+ * the far end too). */
50
11
  hi: string;
51
- /** Gradient low stop (the mid dip). */
12
+ /** Gradient low stop (the dip). */
52
13
  lo: string;
53
14
  /** Dark label color. */
54
15
  text: string;
16
+ /** Far end of the sweep. Default: `hi` (symmetric brushed look). */
17
+ end?: string;
18
+ /** Where `lo` sits, in percent. Default: 50. */
19
+ stop?: number;
55
20
  };
56
21
  /**
57
22
  * Metallic tier chip (PRO / EARLY BIRD / CREATOR): a brushed-metal pill with a
@@ -59,4 +24,4 @@ type TierBadgeProps = ComponentProps<"span"> & {
59
24
  * One family; only the hi/lo/text triplet changes per tier.
60
25
  */
61
26
  declare const TierBadge: Component<TierBadgeProps>;
62
- export { Badge, badgeVariants, TierBadge };
27
+ export { Badge, TierBadge };
@@ -1,5 +1,5 @@
1
1
  import { type Component, type ComponentProps, type JSX, type ParentComponent } from "solid-js";
2
- import { type InitialFocus } from "./focus-trap";
2
+ import { type InitialFocus } from "./focus-trap.js";
3
3
  interface BottomSheetRootProps {
4
4
  open?: boolean;
5
5
  defaultOpen?: boolean;
@@ -1,6 +1,5 @@
1
1
  export declare const EASE = "cubic-bezier(0.32, 0.72, 0, 1)";
2
2
  export declare const TRANSITION_MS = 500;
3
- export declare const TRANSITION_CSS = "transform 500ms cubic-bezier(0.32, 0.72, 0, 1), opacity 500ms cubic-bezier(0.32, 0.72, 0, 1)";
4
3
  export declare const DEAD_ZONE_PX = 6;
5
4
  export declare const CLOSE_DISTANCE_RATIO = 0.4;
6
5
  export declare const CLOSE_VELOCITY_PX_PER_MS = 0.5;
@@ -1,4 +1,4 @@
1
- import type { SheetState } from "./state-machine";
1
+ import type { SheetState } from "./state-machine.js";
2
2
  interface DragHandle {
3
3
  destroy: () => void;
4
4
  }
@@ -1,2 +1 @@
1
- export { BottomSheet, BottomSheetBody, BottomSheetClose, BottomSheetContent, BottomSheetDescription, BottomSheetFooter, BottomSheetHandle, BottomSheetHeader, BottomSheetOverlay, BottomSheetPortal, BottomSheetTitle, BottomSheetTrigger, } from "./bottom-sheet";
2
- export type { SheetState } from "./state-machine";
1
+ export { BottomSheet, BottomSheetBody, BottomSheetClose, BottomSheetContent, BottomSheetDescription, BottomSheetFooter, BottomSheetHandle, BottomSheetHeader, BottomSheetOverlay, BottomSheetPortal, BottomSheetTitle, BottomSheetTrigger, } from "./bottom-sheet.js";
@@ -3,7 +3,7 @@ declare const Breadcrumb: Component<ComponentProps<"nav">>;
3
3
  declare const BreadcrumbList: Component<ComponentProps<"ol">>;
4
4
  declare const BreadcrumbItem: Component<ComponentProps<"li">>;
5
5
  declare const BreadcrumbLink: Component<ComponentProps<"a"> & {
6
- component?: ValidComponent;
6
+ as?: ValidComponent;
7
7
  }>;
8
8
  declare const BreadcrumbPage: Component<ComponentProps<"span">>;
9
9
  declare const BreadcrumbSeparator: ParentComponent<ComponentProps<"li">>;
@@ -1,6 +1,6 @@
1
1
  import { type VariantProps } from "cva";
2
2
  import { type Component, type ComponentProps, type ValidComponent } from "solid-js";
3
- import { Separator } from "./separator";
3
+ import { Separator } from "./separator.js";
4
4
  declare const buttonGroupVariants: import("cva").CVAComponent<Omit<{
5
5
  base: string;
6
6
  variants: {
@@ -30,7 +30,7 @@ declare const buttonGroupVariants: import("cva").CVAComponent<Omit<{
30
30
  }>;
31
31
  declare const ButtonGroup: Component<ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>>;
32
32
  declare const ButtonGroupText: Component<ComponentProps<"div"> & {
33
- component?: ValidComponent;
33
+ as?: ValidComponent;
34
34
  }>;
35
35
  declare const ButtonGroupSeparator: Component<ComponentProps<typeof Separator>>;
36
36
  export { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants };
@@ -1,7 +1,7 @@
1
1
  import { Button as KobalteButton } from "@kobalte/core/button";
2
2
  import type { VariantProps } from "cva";
3
3
  import { type ComponentProps } from "solid-js";
4
- import { buttonVariants } from "../lib/button-variants";
4
+ import { buttonVariants } from "../lib/button-variants.js";
5
5
  type ButtonProps = ComponentProps<typeof KobalteButton> & VariantProps<typeof buttonVariants>;
6
6
  declare function Button(props: ButtonProps): import("solid-js").JSX.Element;
7
7
  export { Button, buttonVariants };
@@ -1,5 +1,13 @@
1
- import { type Component, type ComponentProps } from "solid-js";
2
- declare const Card: Component<ComponentProps<"div">>;
1
+ import { type Component, type ComponentProps, type ValidComponent } from "solid-js";
2
+ import { type CardPadding } from "../lib/card-classes.js";
3
+ type CardProps = ComponentProps<"div"> & {
4
+ interactive?: boolean;
5
+ opaque?: boolean;
6
+ padding?: CardPadding;
7
+ as?: ValidComponent;
8
+ href?: string;
9
+ };
10
+ declare const Card: Component<CardProps>;
3
11
  declare const CardHeader: Component<ComponentProps<"div">>;
4
12
  declare const CardTitle: Component<ComponentProps<"div">>;
5
13
  declare const CardDescription: Component<ComponentProps<"div">>;
@@ -1,6 +1,6 @@
1
1
  import { type EmblaCarouselType, type EmblaOptionsType, type EmblaPluginType } from "embla-carousel";
2
2
  import { type Component, type ComponentProps, type ParentComponent } from "solid-js";
3
- import { Button } from "./button";
3
+ import { Button } from "./button.js";
4
4
  type CarouselApi = EmblaCarouselType;
5
5
  declare const Carousel: ParentComponent<ComponentProps<"div"> & {
6
6
  opts?: EmblaOptionsType;
@@ -0,0 +1,45 @@
1
+ export declare function formatCompact(n: number): string;
2
+ export declare function formatBytes(bytes: number): string;
3
+ /**
4
+ * Filled area + line chart for a daily series. `data` is oldest-first
5
+ * [{day,count}]. Renders a scaling SVG; the caller sizes the container.
6
+ */
7
+ export declare function AreaChart(props: {
8
+ data: {
9
+ day: string;
10
+ count: number;
11
+ }[];
12
+ class?: string;
13
+ height?: number;
14
+ /** Tooltip value formatter (e.g. formatBytes for a size series). */
15
+ format?: (n: number) => string;
16
+ }): import("solid-js").JSX.Element;
17
+ /**
18
+ * Horizontal bar list: one row per item, bar width proportional to `value`.
19
+ * `format` renders the trailing value label (defaults to compact number).
20
+ */
21
+ export declare function BarList(props: {
22
+ items: {
23
+ label: string;
24
+ value: number;
25
+ sublabel?: string;
26
+ href?: string;
27
+ }[];
28
+ format?: (value: number) => string;
29
+ empty?: string;
30
+ }): import("solid-js").JSX.Element;
31
+ /** Segmented control for the chart time window — the shipped Tabs (sliding
32
+ * `.glass` primary indicator). Values are numeric days; Tabs speaks strings, so
33
+ * map at the edge. */
34
+ export declare function RangeToggle(props: {
35
+ value: number;
36
+ onChange: (days: number) => void;
37
+ }): import("solid-js").JSX.Element;
38
+ /** Segmented proportion bar (e.g. staleness fresh/aging/stale). */
39
+ export declare function StackedBar(props: {
40
+ segments: {
41
+ label: string;
42
+ value: number;
43
+ class: string;
44
+ }[];
45
+ }): import("solid-js").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import type { JSX } from "solid-js";
2
+ /**
3
+ * Small neutral count chip (list size, item count) sitting next to a title.
4
+ * The one source for `rounded-full bg-foreground/10 … tabular-nums`, previously
5
+ * hand-inlined in SectionCard, PageHeader, and widget rows.
6
+ */
7
+ export declare function CountPill(props: {
8
+ children: JSX.Element;
9
+ class?: string;
10
+ }): JSX.Element;