@glasshome/widget-sdk 1.22.0 → 1.22.2

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.
@@ -42,5 +42,6 @@ export { injectTokens, type SvgColorKey, svgColors, type Tone, ToneSchema } from
42
42
  export { widgetFields } from "./fields";
43
43
  export { type ConfigShape, defineConfig, field, type Field, type ImagePresetSource, type Infer, } from "./config";
44
44
  export { imageSrc } from "./image-src";
45
- export { calculateLightGroup, calculateSensorGroup, type CopyState, copyText, countActiveEntities, getEntityAttribute, isEntityActive, type LightGroupResult, type SensorGroupResult, type SensorGroupType, useCopyText, } from "./utils";
45
+ export { type CopyState, copyText, useCopyText } from "@glasshome/ui/solid";
46
+ export { calculateLightGroup, calculateSensorGroup, countActiveEntities, getEntityAttribute, isEntityActive, type LightGroupResult, type SensorGroupResult, type SensorGroupType, } from "./utils";
46
47
  export type { EntityView, WidgetStyles, WidgetVariantConfig } from "./types";
@@ -5,7 +5,6 @@
5
5
  * in this directory are still consumed internally even when not part of the
6
6
  * public re-export surface.
7
7
  */
8
- export { copyText, type CopyState, useCopyText } from "./clipboard";
9
8
  export { calculateLightGroup, calculateSensorGroup, type LightGroupResult, type SensorGroupResult, type SensorGroupType, } from "./entity-aggregation";
10
9
  export { countActiveEntities, getEntityAttribute, isEntityActive } from "./entity-state";
11
10
  export { formatValue } from "./format-value";
package/dist/index.js CHANGED
@@ -5,11 +5,11 @@ import { getForecasts as s, getStream as c, getWebRtcClientConfig as l, hassMedi
5
5
  import { byDomain as g, useArea as _, useCalendarEvents as v, useCamera as y, useConnection as b, useCurrency as x, useEntities as S, useEntity as ee, useEntity as C, useEntityHistory as w, useEntityStatistics as te, useForecast as ne, useHassConfig as re, useLocale as ie, useService as ae, useStore as oe, useTemperatureUnit as se, useToggle as ce, useTurnOff as le, useTurnOn as ue, useUnitSystem as de } from "@glasshome/sync-layer/solid";
6
6
  import { For as T, Show as E, children as fe, createContext as pe, createEffect as D, createMemo as O, createSignal as k, on as me, onCleanup as A, onMount as he, splitProps as ge, useContext as j } from "solid-js";
7
7
  import { addEventListener as M, className as N, createComponent as P, delegateEvents as _e, effect as F, insert as I, memo as L, setAttribute as R, setStyleProperty as z, style as B, template as V, use as H } from "solid-js/web";
8
- import { Accordion as ve, AccordionContent as ye, AccordionItem as be, AccordionTrigger as xe, Badge as Se, Badge as Ce, Button as we, Button as Te, ButtonGroup as Ee, ButtonGroup as De, Carousel as Oe, CarouselContent as ke, CarouselDots as Ae, CarouselItem as je, CarouselNext as Me, CarouselPrevious as Ne, ColorDisc as Pe, ColorSlider as Fe, ColorWheel as Ie, CountPill as Le, CountPill as Re, Empty as ze, EmptyDescription as Be, EmptyHeader as Ve, EmptyTitle as He, FactRow as Ue, FieldGroup as We, FieldTitle as Ge, HOLD_GRACE_MS as Ke, HOLD_MS as qe, Icon as Je, Icon as U, Input as Ye, Label as Xe, Popover as Ze, PopoverContent as Qe, Progress as $e, ResponsiveDialog as et, ResponsiveDialogBody as tt, ResponsiveDialogBody as nt, ResponsiveDialogClose as rt, ResponsiveDialogContent as it, ResponsiveDialogDescription as at, ResponsiveDialogFooter as ot, ResponsiveDialogFooter as st, ResponsiveDialogHeader as ct, ResponsiveDialogTitle as lt, SchemaForm as ut, SectionIcon as dt, SectionIcon as ft, SectionMeta as pt, SectionRow as mt, SectionTitle as ht, Select as gt, SelectContent as _t, SelectItem as vt, SelectTrigger as yt, SelectValue as bt, Slider as xt, SwatchPicker as St, Switch as Ct, Tabs as wt, Tabs as Tt, TabsContent as Et, TabsContent as Dt, TabsList as Ot, TabsList as kt, TabsTrigger as At, TabsTrigger as jt, TemperatureBar as Mt, Toggle as Nt, ToggleGroup as Pt, ToggleGroup as Ft, ToggleGroupItem as It, ToggleGroupItem as Lt, buttonVariants as Rt, imagePreset as zt, imagePreset as Bt, imageUrl as Vt, imageUrl as Ht, mediaUrl as Ut, parseColor as Wt, presetValue as Gt } from "@glasshome/ui/solid";
9
- import { clsx as Kt } from "clsx";
10
- import { twMerge as qt } from "tailwind-merge";
8
+ import { Accordion as ve, AccordionContent as ye, AccordionItem as be, AccordionTrigger as xe, Badge as Se, Badge as Ce, Button as we, Button as Te, ButtonGroup as Ee, ButtonGroup as De, Carousel as Oe, CarouselContent as ke, CarouselDots as Ae, CarouselItem as je, CarouselNext as Me, CarouselPrevious as Ne, ColorDisc as Pe, ColorSlider as Fe, ColorWheel as Ie, CountPill as Le, CountPill as Re, Empty as ze, EmptyDescription as Be, EmptyHeader as Ve, EmptyTitle as He, FactRow as Ue, FieldGroup as We, FieldTitle as Ge, HOLD_GRACE_MS as Ke, HOLD_MS as qe, Icon as Je, Icon as U, Input as Ye, Label as Xe, Popover as Ze, PopoverContent as Qe, Progress as $e, ResponsiveDialog as et, ResponsiveDialogBody as tt, ResponsiveDialogBody as nt, ResponsiveDialogClose as rt, ResponsiveDialogContent as it, ResponsiveDialogDescription as at, ResponsiveDialogFooter as ot, ResponsiveDialogFooter as st, ResponsiveDialogHeader as ct, ResponsiveDialogTitle as lt, SchemaForm as ut, SectionIcon as dt, SectionIcon as ft, SectionMeta as pt, SectionRow as mt, SectionTitle as ht, Select as gt, SelectContent as _t, SelectItem as vt, SelectTrigger as yt, SelectValue as bt, Slider as xt, SwatchPicker as St, Switch as Ct, Tabs as wt, Tabs as Tt, TabsContent as Et, TabsContent as Dt, TabsList as Ot, TabsList as kt, TabsTrigger as At, TabsTrigger as jt, TemperatureBar as Mt, Toggle as Nt, ToggleGroup as Pt, ToggleGroup as Ft, ToggleGroupItem as It, ToggleGroupItem as Lt, buttonVariants as Rt, copyText as zt, imagePreset as Bt, imagePreset as Vt, imageUrl as Ht, imageUrl as Ut, mediaUrl as Wt, parseColor as Gt, presetValue as Kt, spendLongPress as qt, useCopyText as Jt, useCopyText as Yt } from "@glasshome/ui/solid";
9
+ import { clsx as Xt } from "clsx";
10
+ import { twMerge as Zt } from "tailwind-merge";
11
11
  //#region src/framework/to-form-schema.ts
12
- function Jt(e) {
12
+ function Qt(e) {
13
13
  return o.toJSONSchema(e, { override: (e) => {
14
14
  let t = o.globalRegistry.get(e.zodSchema);
15
15
  return t && typeof t == "object" && Object.keys(t).length > 0 ? {
@@ -18,7 +18,7 @@ function Jt(e) {
18
18
  } : e.jsonSchema;
19
19
  } });
20
20
  }
21
- function Yt(e) {
21
+ function $t(e) {
22
22
  try {
23
23
  return e.parse({});
24
24
  } catch {
@@ -27,59 +27,59 @@ function Yt(e) {
27
27
  }
28
28
  //#endregion
29
29
  //#region src/define-widget.ts
30
- function Xt(e) {
31
- return e.configSchema && (e.manifest.schema || (e.manifest.schema = Jt(e.configSchema)), e.manifest.defaultConfig || (e.manifest.defaultConfig = Yt(e.configSchema))), e;
30
+ function en(e) {
31
+ return e.configSchema && (e.manifest.schema || (e.manifest.schema = Qt(e.configSchema)), e.manifest.defaultConfig || (e.manifest.defaultConfig = $t(e.configSchema))), e;
32
32
  }
33
33
  //#endregion
34
34
  //#region src/framework/hooks/use-widget-context.ts
35
35
  var W = pe();
36
- function Zt() {
36
+ function tn() {
37
37
  let e = j(W);
38
38
  if (!e) throw Error("useWidgetContext must be used within a Widget component");
39
39
  return e;
40
40
  }
41
41
  //#endregion
42
42
  //#region src/framework/hooks/use-service.ts
43
- function Qt(e) {
43
+ function nn(e) {
44
44
  let t = Array.isArray(e) ? e[0] : e, n = t?.split(".")[0];
45
45
  if (!n) throw Error(`Invalid entity ID: ${String(t)}`);
46
46
  return n;
47
47
  }
48
- function $t(e, t) {
48
+ function rn(e, t) {
49
49
  return async (n, r = {}) => {
50
- await e(Qt(n), t, r, { entity_id: n });
50
+ await e(nn(n), t, r, { entity_id: n });
51
51
  };
52
52
  }
53
- function en() {
53
+ function an() {
54
54
  let e = j(W)?.callService;
55
55
  return e ? {
56
56
  callService: e,
57
- turnOn: $t(e, "turn_on"),
58
- turnOff: $t(e, "turn_off"),
59
- toggle: $t(e, "toggle")
57
+ turnOn: rn(e, "turn_on"),
58
+ turnOff: rn(e, "turn_off"),
59
+ toggle: rn(e, "toggle")
60
60
  } : ae();
61
61
  }
62
- function tn() {
62
+ function on() {
63
63
  let e = j(W)?.callService;
64
- return e ? $t(e, "turn_on") : ue();
64
+ return e ? rn(e, "turn_on") : ue();
65
65
  }
66
- function nn() {
66
+ function sn() {
67
67
  let e = j(W)?.callService;
68
- return e ? $t(e, "turn_off") : le();
68
+ return e ? rn(e, "turn_off") : le();
69
69
  }
70
- function rn() {
70
+ function cn() {
71
71
  let e = j(W)?.callService;
72
- return e ? $t(e, "toggle") : ce();
72
+ return e ? rn(e, "toggle") : ce();
73
73
  }
74
74
  //#endregion
75
75
  //#region src/framework/design-system/z-index.ts
76
- var an = {
76
+ var ln = {
77
77
  BACKGROUND: 0,
78
78
  CONTENT: 10,
79
79
  OVERLAY: 20,
80
80
  ACTIONS: 30
81
81
  }, G = /* @__PURE__ */ new WeakMap();
82
- function on(e = "controls") {
82
+ function un(e = "controls") {
83
83
  let [t, n] = k(!1), [r, i] = k(e), a = (t) => {
84
84
  i(t ?? e), n(!0);
85
85
  }, o = j(W);
@@ -106,13 +106,13 @@ function on(e = "controls") {
106
106
  }
107
107
  //#endregion
108
108
  //#region src/framework/hooks/widget-registry.ts
109
- var sn = /* @__PURE__ */ new WeakMap(), cn = Symbol("glasshome.widget.registry");
110
- function ln(e) {
111
- return e[cn] ?? e;
109
+ var dn = /* @__PURE__ */ new WeakMap(), fn = Symbol("glasshome.widget.registry");
110
+ function pn(e) {
111
+ return e[fn] ?? e;
112
112
  }
113
- function un(e) {
113
+ function mn(e) {
114
114
  if (!e) return;
115
- let t = ln(e), n = sn.get(t);
115
+ let t = pn(e), n = dn.get(t);
116
116
  if (!n) {
117
117
  let [e, r] = k(!1), [i, a] = k(), [o, s] = k(), [c, l] = k(), [u, d] = k(!1);
118
118
  n = {
@@ -126,46 +126,46 @@ function un(e) {
126
126
  setIcon: l,
127
127
  nothingMore: u,
128
128
  setNothingMore: d
129
- }, sn.set(t, n);
129
+ }, dn.set(t, n);
130
130
  }
131
131
  return n;
132
132
  }
133
133
  //#endregion
134
134
  //#region src/framework/gestures/cursors.ts
135
- var dn = 32, K = dn / 2, q = "white", fn = "rgba(0,0,0,0.4)", pn = 2, mn = 3;
136
- function hn(e) {
135
+ var hn = 32, K = hn / 2, q = "white", gn = "rgba(0,0,0,0.4)", _n = 2, vn = 3;
136
+ function yn(e) {
137
137
  return `url("data:image/svg+xml,${encodeURIComponent(e)}")`;
138
138
  }
139
- function gn(e) {
140
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${dn}" height="${dn}" viewBox="0 0 ${dn} ${dn}">${e}</svg>`;
139
+ function bn(e) {
140
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${hn}" height="${hn}" viewBox="0 0 ${hn} ${hn}">${e}</svg>`;
141
141
  }
142
- var _n = gn(`
142
+ var xn = bn(`
143
143
  <g transform="translate(6, 2)">
144
144
  <!-- shadow -->
145
- <g stroke="${fn}" stroke-width="${mn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
145
+ <g stroke="${gn}" stroke-width="${vn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
146
146
  <path d="M10 8V3a2 2 0 0 1 4 0v10l4.5-4.5a2 2 0 0 1 2.83 2.83L14 18.5c-2 2-4 3.5-8 3.5-3 0-5-2-5-5v-6a2 2 0 0 1 4 0v2"/>
147
147
  </g>
148
148
  <!-- main -->
149
- <g stroke="${q}" stroke-width="${pn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
149
+ <g stroke="${q}" stroke-width="${_n}" fill="none" stroke-linecap="round" stroke-linejoin="round">
150
150
  <path d="M10 8V3a2 2 0 0 1 4 0v10l4.5-4.5a2 2 0 0 1 2.83 2.83L14 18.5c-2 2-4 3.5-8 3.5-3 0-5-2-5-5v-6a2 2 0 0 1 4 0v2"/>
151
151
  </g>
152
152
  </g>
153
- `), vn = gn(`
153
+ `), Sn = bn(`
154
154
  <g>
155
- <circle cx="${K}" cy="${K}" r="8" stroke="${fn}" stroke-width="${mn}" fill="none"/>
155
+ <circle cx="${K}" cy="${K}" r="8" stroke="${gn}" stroke-width="${vn}" fill="none"/>
156
156
  <circle cx="${K}" cy="${K}" r="8" stroke="${q}" stroke-width="1.5" fill="none"/>
157
157
  <circle cx="${K}" cy="${K}" r="1.5" fill="${q}"/>
158
158
  </g>
159
- `), yn = gn(`
159
+ `), Cn = bn(`
160
160
  <g>
161
161
  <!-- shadow -->
162
- <g stroke="${fn}" stroke-width="${mn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
162
+ <g stroke="${gn}" stroke-width="${vn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
163
163
  <line x1="6" y1="${K}" x2="26" y2="${K}"/>
164
164
  <polyline points="10,12 6,${K} 10,20"/>
165
165
  <polyline points="22,12 26,${K} 22,20"/>
166
166
  </g>
167
167
  <!-- main -->
168
- <g stroke="${q}" stroke-width="${pn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
168
+ <g stroke="${q}" stroke-width="${_n}" fill="none" stroke-linecap="round" stroke-linejoin="round">
169
169
  <line x1="6" y1="${K}" x2="26" y2="${K}"/>
170
170
  <polyline points="10,12 6,${K} 10,20"/>
171
171
  <polyline points="22,12 26,${K} 22,20"/>
@@ -175,16 +175,16 @@ var _n = gn(`
175
175
  <circle cx="11" cy="${K}" r="1" fill="${q}" opacity="0.6"/>
176
176
  <circle cx="21" cy="${K}" r="1" fill="${q}" opacity="0.6"/>
177
177
  </g>
178
- `), bn = gn(`
178
+ `), wn = bn(`
179
179
  <g>
180
180
  <!-- shadow -->
181
- <g stroke="${fn}" stroke-width="${mn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
181
+ <g stroke="${gn}" stroke-width="${vn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
182
182
  <line x1="${K}" y1="6" x2="${K}" y2="26"/>
183
183
  <polyline points="12,10 ${K},6 20,10"/>
184
184
  <polyline points="12,22 ${K},26 20,22"/>
185
185
  </g>
186
186
  <!-- main -->
187
- <g stroke="${q}" stroke-width="${pn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
187
+ <g stroke="${q}" stroke-width="${_n}" fill="none" stroke-linecap="round" stroke-linejoin="round">
188
188
  <line x1="${K}" y1="6" x2="${K}" y2="26"/>
189
189
  <polyline points="12,10 ${K},6 20,10"/>
190
190
  <polyline points="12,22 ${K},26 20,22"/>
@@ -194,10 +194,10 @@ var _n = gn(`
194
194
  <circle cx="${K}" cy="11" r="1" fill="${q}" opacity="0.6"/>
195
195
  <circle cx="${K}" cy="21" r="1" fill="${q}" opacity="0.6"/>
196
196
  </g>
197
- `), xn = gn(`
197
+ `), Tn = bn(`
198
198
  <g>
199
199
  <!-- shadow -->
200
- <g stroke="${fn}" stroke-width="${mn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
200
+ <g stroke="${gn}" stroke-width="${vn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
201
201
  <line x1="7" y1="${K}" x2="25" y2="${K}"/>
202
202
  <line x1="${K}" y1="7" x2="${K}" y2="25"/>
203
203
  <polyline points="11,13 7,${K} 11,19"/>
@@ -206,7 +206,7 @@ var _n = gn(`
206
206
  <polyline points="13,21 ${K},25 19,21"/>
207
207
  </g>
208
208
  <!-- main -->
209
- <g stroke="${q}" stroke-width="${pn}" fill="none" stroke-linecap="round" stroke-linejoin="round">
209
+ <g stroke="${q}" stroke-width="${_n}" fill="none" stroke-linecap="round" stroke-linejoin="round">
210
210
  <line x1="7" y1="${K}" x2="25" y2="${K}"/>
211
211
  <line x1="${K}" y1="7" x2="${K}" y2="25"/>
212
212
  <polyline points="11,13 7,${K} 11,19"/>
@@ -218,65 +218,53 @@ var _n = gn(`
218
218
  <circle cx="${K}" cy="${K}" r="2" fill="${q}"/>
219
219
  </g>
220
220
  `);
221
- function Sn(e, t, n) {
221
+ function En(e, t, n) {
222
222
  return {
223
- css: `${hn(e)} ${t} ${n}, auto`,
223
+ css: `${yn(e)} ${t} ${n}, auto`,
224
224
  hotspotX: t,
225
225
  hotspotY: n
226
226
  };
227
227
  }
228
- var Cn = {
229
- tap: Sn(_n, 12, 4),
230
- hold: Sn(vn, 16, 16),
231
- slideHorizontal: Sn(yn, K, K),
232
- slideVertical: Sn(bn, K, K),
233
- slideAuto: Sn(xn, K, K)
228
+ var Dn = {
229
+ tap: En(xn, 12, 4),
230
+ hold: En(Sn, 16, 16),
231
+ slideHorizontal: En(Cn, K, K),
232
+ slideVertical: En(wn, K, K),
233
+ slideAuto: En(Tn, K, K)
234
234
  };
235
235
  //#endregion
236
236
  //#region src/framework/gestures/haptics.ts
237
- function wn() {
237
+ function On() {
238
238
  if (typeof window > "u") return null;
239
239
  let e = window;
240
240
  return e.Capacitor?.isNativePlatform?.() ? e.Capacitor.Plugins?.Haptics ?? null : null;
241
241
  }
242
- function Tn(e) {
242
+ function kn(e) {
243
243
  if (typeof navigator < "u" && typeof navigator.vibrate == "function") try {
244
244
  navigator.vibrate(e);
245
245
  } catch {}
246
246
  }
247
- var En = {
247
+ var An = {
248
248
  tick() {
249
- let e = wn();
250
- if (e) {
251
- e.impact({ style: "Light" }).catch(() => {});
252
- return;
253
- }
254
- Tn(8);
249
+ let e = On();
250
+ e ? e.impact({ style: "Light" }).catch(() => {}) : kn(8);
255
251
  },
256
252
  bump() {
257
- let e = wn();
258
- if (e) {
259
- e.impact({ style: "Medium" }).catch(() => {});
260
- return;
261
- }
262
- Tn(20);
253
+ let e = On();
254
+ e ? e.impact({ style: "Medium" }).catch(() => {}) : kn(20);
263
255
  },
264
256
  pulse() {
265
- let e = wn();
266
- if (e) {
267
- e.impact({ style: "Heavy" }).catch(() => {});
268
- return;
269
- }
270
- Tn([
257
+ let e = On();
258
+ e ? e.impact({ style: "Heavy" }).catch(() => {}) : kn([
271
259
  0,
272
260
  15,
273
261
  40,
274
262
  15
275
263
  ]);
276
264
  }
277
- }, Dn = "button, a, input, select, textarea, [role=\"slider\"], [role=\"radio\"], [role=\"switch\"]";
278
- function On(e, t) {
279
- let n = j(W), r = un(n), i = () => {
265
+ }, jn = "button, a, input, select, textarea, [role=\"slider\"], [role=\"radio\"], [role=\"switch\"]";
266
+ function Mn(e, t) {
267
+ let n = j(W), r = mn(n), i = () => {
280
268
  let t = e();
281
269
  return t.hold || !n ? t : {
282
270
  ...t,
@@ -329,7 +317,7 @@ function On(e, t) {
329
317
  let n = i().slide;
330
318
  return n?.orientation === "horizontal" ? "horizontal" : n?.orientation === "vertical" ? "vertical" : e && (c || p(e), c) ? c.height > c.width ? "vertical" : "horizontal" : (t?.() ?? "horizontal") === "horizontal" ? "horizontal" : "vertical";
331
319
  }, v = (e) => {
332
- let t = i(), r = e.target instanceof Element ? e.target.closest(`${Dn}, .glasshome-widget-controls`) : null, o = r !== null && r !== e.currentTarget;
320
+ let t = i(), r = e.target instanceof Element ? e.target.closest(`${jn}, .glasshome-widget-controls`) : null, o = r !== null && r !== e.currentTarget;
333
321
  if (!(o ? !t.hold : !t.tap && !t.hold && !t.slide)) {
334
322
  if (a.isDown = !0, a.holdOnly = o, a.isTouch = e.pointerType === "touch", a.element = e.currentTarget, p(a.element), a.startX = e.clientX, a.startY = e.clientY, a.startTime = Date.now(), a.hasMoved = !1, a.sliding = !1, t.hold) {
335
323
  let r = t.hold.delay ?? qe, i = a.element.getBoundingClientRect(), o = e.clientX - i.left, c = e.clientY - i.top, l = Math.hypot(Math.max(o, i.width - o), Math.max(c, i.height - c));
@@ -344,7 +332,7 @@ function On(e, t) {
344
332
  a.holdTimer = null, a.isDown && !a.hasMoved && (s((e) => e && {
345
333
  ...e,
346
334
  fired: !0
347
- }), En.bump(), a.element && h(a.element), t.hold?.action(), n?.onHeld?.(), a.isDown = !1);
335
+ }), An.bump(), qt(), a.element && h(a.element), t.hold?.action(), n?.onHeld?.(), a.isDown = !1);
348
336
  }, r);
349
337
  }
350
338
  if (!a.isTouch && t.slide && !o) try {
@@ -381,9 +369,9 @@ function On(e, t) {
381
369
  let t = i();
382
370
  if (t.slide) {
383
371
  let n = t.slide.orientation;
384
- return n === "horizontal" ? Cn.slideHorizontal.css : n === "vertical" ? Cn.slideVertical.css : (c || p(e), c && c.height > c.width ? Cn.slideVertical.css : Cn.slideHorizontal.css);
372
+ return n === "horizontal" ? Dn.slideHorizontal.css : n === "vertical" ? Dn.slideVertical.css : (c || p(e), c && c.height > c.width ? Dn.slideVertical.css : Dn.slideHorizontal.css);
385
373
  }
386
- return t.tap ? Cn.tap.css : t.hold ? Cn.hold.css : "";
374
+ return t.tap ? Dn.tap.css : t.hold ? Dn.hold.css : "";
387
375
  };
388
376
  return {
389
377
  onKeyDown: (e) => {
@@ -419,16 +407,16 @@ function On(e, t) {
419
407
  }
420
408
  //#endregion
421
409
  //#region src/framework/hooks/use-widget-dimensions.ts
422
- var kn = pe();
423
- function An() {
424
- let e = j(kn);
410
+ var Nn = pe();
411
+ function Pn() {
412
+ let e = j(Nn);
425
413
  if (!e) throw Error("useWidgetDimensions must be called inside <Widget>: move the call into a component rendered within <Widget> (the top-level widget scope only sees the host stub).");
426
414
  return e;
427
415
  }
428
416
  //#endregion
429
417
  //#region src/framework/hooks/use-confirm.ts
430
- var jn = 1600;
431
- function Mn() {
418
+ var Fn = 1600;
419
+ function In() {
432
420
  let [e, t] = k(/* @__PURE__ */ new Set()), n;
433
421
  return A(() => clearTimeout(n)), {
434
422
  has: (t) => e().has(t),
@@ -439,35 +427,35 @@ function Mn() {
439
427
  } catch {
440
428
  return !1;
441
429
  }
442
- return t(new Set(e)), clearTimeout(n), n = setTimeout(() => t(/* @__PURE__ */ new Set()), jn), !0;
430
+ return t(new Set(e)), clearTimeout(n), n = setTimeout(() => t(/* @__PURE__ */ new Set()), Fn), !0;
443
431
  }
444
432
  };
445
433
  }
446
434
  //#endregion
447
435
  //#region src/framework/utils/cn.ts
448
436
  function J(...e) {
449
- return qt(Kt(e));
437
+ return Zt(Xt(e));
450
438
  }
451
439
  //#endregion
452
440
  //#region src/framework/components/WidgetIcon.tsx
453
- var Nn = /*#__PURE__*/ V("<div class=\"glasshome-widget-icon glasshome-widget-icon-stack glasshome-widget-icon-stack-2 glass glass-tint\">"), Pn = /*#__PURE__*/ V("<div class=\"glasshome-widget-icon glasshome-widget-icon-stack glasshome-widget-icon-stack-3 glass glass-tint\">"), Fn = /*#__PURE__*/ V("<div><div class=\"glasshome-widget-icon-glyph flex items-center justify-center\">");
454
- function In(e) {
441
+ var Ln = /*#__PURE__*/ V("<div class=\"glasshome-widget-icon glasshome-widget-icon-stack glasshome-widget-icon-stack-2 glass glass-tint\">"), Rn = /*#__PURE__*/ V("<div class=\"glasshome-widget-icon glasshome-widget-icon-stack glasshome-widget-icon-stack-3 glass glass-tint\">"), zn = /*#__PURE__*/ V("<div><div class=\"glasshome-widget-icon-glyph flex items-center justify-center\">");
442
+ function Bn(e) {
455
443
  let t = () => e.entityCount ?? 1;
456
444
  return (() => {
457
- var n = Fn(), r = n.firstChild;
445
+ var n = zn(), r = n.firstChild;
458
446
  return I(n, P(E, {
459
447
  get when() {
460
448
  return t() >= 2;
461
449
  },
462
450
  get children() {
463
- return Nn();
451
+ return Ln();
464
452
  }
465
453
  }), r), I(n, P(E, {
466
454
  get when() {
467
455
  return t() >= 3;
468
456
  },
469
457
  get children() {
470
- return Pn();
458
+ return Rn();
471
459
  }
472
460
  }), r), I(r, () => e.icon), F((t) => {
473
461
  var r = J("glasshome-widget-icon glass glass-tint", "pointer-events-none relative flex shrink-0 items-center justify-center transition-all", e.dimmed && "opacity-50", e.class), i = e.color ? { "--widget-icon-color": e.color } : void 0;
@@ -480,9 +468,9 @@ function In(e) {
480
468
  }
481
469
  //#endregion
482
470
  //#region src/framework/components/anatomy.tsx
483
- var Ln = /*#__PURE__*/ V("<span class=glasshome-widget-eyebrow>"), Rn = /*#__PURE__*/ V("<div class=glasshome-widget-head-aside>"), zn = /*#__PURE__*/ V("<div class=glasshome-widget-head><div class=glasshome-widget-head-text><span class=glasshome-widget-name>"), Bn = /*#__PURE__*/ V("<span class=glasshome-widget-sub>"), Vn = /*#__PURE__*/ V("<span class=glasshome-widget-unit>"), Hn = /*#__PURE__*/ V("<div class=glasshome-widget-art>"), Un = /*#__PURE__*/ V("<div><div class=glasshome-widget-reading><span class=glasshome-widget-reading-value>"), Wn = /*#__PURE__*/ V("<div class=glasshome-widget-controls>"), Gn = /*#__PURE__*/ V("<div>"), Kn = /*#__PURE__*/ V("<div class=glasshome-widget-backdrop>"), qn = /*#__PURE__*/ V("<div class=glasshome-widget-glyph aria-hidden=true>"), Jn = pe(() => !1), Yn = "mdi:check";
484
- function Xn(e) {
485
- let t = j(Jn), n = un(j(W));
471
+ var Vn = /*#__PURE__*/ V("<span class=glasshome-widget-eyebrow>"), Hn = /*#__PURE__*/ V("<div class=glasshome-widget-head-aside>"), Un = /*#__PURE__*/ V("<div class=glasshome-widget-head><div class=glasshome-widget-head-text><span class=glasshome-widget-name>"), Wn = /*#__PURE__*/ V("<span class=glasshome-widget-sub>"), Gn = /*#__PURE__*/ V("<span class=glasshome-widget-unit>"), Kn = /*#__PURE__*/ V("<div class=glasshome-widget-art>"), qn = /*#__PURE__*/ V("<div><div class=glasshome-widget-reading><span class=glasshome-widget-reading-value>"), Jn = /*#__PURE__*/ V("<div class=glasshome-widget-controls>"), Yn = /*#__PURE__*/ V("<div>"), Xn = /*#__PURE__*/ V("<div class=glasshome-widget-backdrop>"), Zn = /*#__PURE__*/ V("<div class=glasshome-widget-glyph aria-hidden=true>"), Qn = pe(() => !1), $n = "mdi:check";
472
+ function er(e) {
473
+ let t = j(Qn), n = mn(j(W));
486
474
  D(() => n?.setIcon(e.icon)), A(() => {
487
475
  n?.icon() === e.icon && n?.setIcon(void 0);
488
476
  });
@@ -491,15 +479,15 @@ function Xn(e) {
491
479
  return typeof t == "string" && typeof e.name == "string" && t.trim().toLowerCase() === e.name.trim().toLowerCase();
492
480
  };
493
481
  return (() => {
494
- var n = zn(), o = n.firstChild, s = o.firstChild;
482
+ var n = Un(), o = n.firstChild, s = o.firstChild;
495
483
  return I(n, P(E, {
496
484
  get when() {
497
485
  return e.icon;
498
486
  },
499
- children: (n) => P(In, {
487
+ children: (n) => P(Bn, {
500
488
  get icon() {
501
489
  return P(U, { get icon() {
502
- return L(() => !!t())() ? Yn : n();
490
+ return L(() => !!t())() ? $n : n();
503
491
  } });
504
492
  },
505
493
  get entityCount() {
@@ -515,7 +503,7 @@ function Xn(e) {
515
503
  return L(() => !!r())() && !a();
516
504
  },
517
505
  get children() {
518
- var e = Ln();
506
+ var e = Vn();
519
507
  return I(e, r), e;
520
508
  }
521
509
  }), s), I(s, () => e.name), I(n, P(E, {
@@ -523,22 +511,22 @@ function Xn(e) {
523
511
  return i();
524
512
  },
525
513
  get children() {
526
- var e = Rn();
514
+ var e = Hn();
527
515
  return I(e, i), e;
528
516
  }
529
517
  }), null), n;
530
518
  })();
531
519
  }
532
- function Zn(e) {
520
+ function tr(e) {
533
521
  let t = fe(() => e.sub), n = fe(() => e.art), r = O(() => typeof e.value == "string" ? e.value.replace(/[\d\s.,:/%°+\-−]/g, "") : void 0), i = () => typeof e.value == "string" || typeof e.value == "number" ? String(e.value).length + (e.unit ? .5 : 0) : void 0, [a, o] = k();
534
522
  return D(me(r, () => o((e) => e === "a" ? "b" : "a"), { defer: !0 })), (() => {
535
- var r = Un(), o = r.firstChild, s = o.firstChild;
523
+ var r = qn(), o = r.firstChild, s = o.firstChild;
536
524
  return I(o, P(E, {
537
525
  get when() {
538
526
  return t();
539
527
  },
540
528
  get children() {
541
- var e = Bn();
529
+ var e = Wn();
542
530
  return I(e, t), e;
543
531
  }
544
532
  }), s), I(s, () => e.value, null), I(s, P(E, {
@@ -546,7 +534,7 @@ function Zn(e) {
546
534
  return e.unit;
547
535
  },
548
536
  get children() {
549
- var t = Vn();
537
+ var t = Gn();
550
538
  return I(t, () => e.unit), F(() => R(t, "data-degree", e.unit === "°" || void 0)), t;
551
539
  }
552
540
  }), null), I(r, P(E, {
@@ -554,7 +542,7 @@ function Zn(e) {
554
542
  return n();
555
543
  },
556
544
  get children() {
557
- var e = Hn();
545
+ var e = Kn();
558
546
  return I(e, n), e;
559
547
  }
560
548
  }), null), F((o) => {
@@ -569,13 +557,13 @@ function Zn(e) {
569
557
  }), r;
570
558
  })();
571
559
  }
572
- function Qn(e) {
560
+ function nr(e) {
573
561
  return (() => {
574
- var t = Wn();
562
+ var t = Jn();
575
563
  return I(t, () => e.children), t;
576
564
  })();
577
565
  }
578
- function $n(e) {
566
+ function rr(e) {
579
567
  return P(De, {
580
568
  get "aria-label"() {
581
569
  return e.label;
@@ -604,7 +592,7 @@ function $n(e) {
604
592
  }
605
593
  });
606
594
  }
607
- function er(e) {
595
+ function ir(e) {
608
596
  return P(Ft, {
609
597
  get "aria-label"() {
610
598
  return e.label;
@@ -643,8 +631,8 @@ function er(e) {
643
631
  }
644
632
  });
645
633
  }
646
- function tr(e) {
647
- let t = Mn(), n = () => e.confirm ?? t, r = () => e.id ?? e["aria-label"] ?? e.icon, i = () => n().has(r());
634
+ function ar(e) {
635
+ let t = In(), n = () => e.confirm ?? t, r = () => e.id ?? e["aria-label"] ?? e.icon, i = () => n().has(r());
648
636
  return P(Te, {
649
637
  variant: "outline",
650
638
  get size() {
@@ -662,12 +650,12 @@ function tr(e) {
662
650
  onClick: () => void n().run([r()], e.run),
663
651
  get children() {
664
652
  return [P(U, { get icon() {
665
- return L(() => !!i())() ? Yn : e.icon;
653
+ return L(() => !!i())() ? $n : e.icon;
666
654
  } }), L(() => e.children)];
667
655
  }
668
656
  });
669
657
  }
670
- function nr(e) {
658
+ function or(e) {
671
659
  return P(Ce, {
672
660
  get tone() {
673
661
  return e.tone ?? "var(--muted-foreground)";
@@ -685,53 +673,53 @@ function nr(e) {
685
673
  }
686
674
  });
687
675
  }
688
- function rr(e) {
676
+ function sr(e) {
689
677
  return (() => {
690
- var t = Gn();
678
+ var t = Yn();
691
679
  return I(t, () => e.children), F(() => N(t, J("glasshome-widget-layer", e.class))), t;
692
680
  })();
693
681
  }
694
- function ir(e) {
682
+ function cr(e) {
695
683
  return (() => {
696
- var t = Kn();
684
+ var t = Xn();
697
685
  return I(t, () => e.children), t;
698
686
  })();
699
687
  }
700
- function ar(e) {
701
- let t = j(Jn);
688
+ function lr(e) {
689
+ let t = j(Qn);
702
690
  return (() => {
703
- var n = qn();
691
+ var n = Zn();
704
692
  return I(n, P(U, { get icon() {
705
- return L(() => !!t())() ? Yn : e.icon;
693
+ return L(() => !!t())() ? $n : e.icon;
706
694
  } })), n;
707
695
  })();
708
696
  }
709
697
  //#endregion
710
698
  //#region src/framework/theming/tokens.css?raw
711
- var or = "/* Authoritative SDK CSS contract. Injected once on first Widget mount\n * via framework/theming/tokens.ts.\n *\n * All widget-internal visual scale is driven from CSS custom properties +\n * container queries on the `.glasshome-widget` shell (`container-type: size`).\n * No JS classifier, no size tier enum.\n */\n\n:root {\n --tone-success: oklch(0.7 0.18 145);\n --tone-warning: oklch(0.8 0.17 75);\n --tone-danger: oklch(0.64 0.22 27);\n --tone-info: oklch(0.66 0.2 245);\n --tone-neutral: oklch(0.65 0.02 250);\n --tone-accent: oklch(0.74 0.18 60);\n\n --widget-glow-default: 0.4;\n}\n\n.dark {\n --tone-success: oklch(0.74 0.18 145);\n --tone-warning: oklch(0.82 0.17 75);\n --tone-danger: oklch(0.68 0.22 27);\n --tone-info: oklch(0.7 0.2 245);\n --tone-neutral: oklch(0.69 0.02 250);\n --tone-accent: oklch(0.78 0.18 60);\n\n --widget-glow-default: 0.5;\n}\n\n@property --widget-color {\n syntax: \"<color>\";\n inherits: true;\n initial-value: oklch(0.65 0.02 250);\n}\n\n/* === Widget shell ===\n * One scale: --widget-unit is 1% of the shell's short side. Each size is a floor,\n * a line through the designed 2x2 and 4x4 sizes, and past 4x4 the share it has\n * at 4x4. A widget sizes its own text with these tokens and scales with every tile. */\n.glasshome-widget {\n --widget-color: var(--tone-neutral);\n --widget-glow-strength: var(--widget-glow-default);\n --widget-radius: var(--radius-xl, 12px);\n\n --widget-unit: 1cqmin;\n --widget-text-value: max(\n 22px,\n calc(8.5px + 13.4 * var(--widget-unit)),\n calc(16 * var(--widget-unit))\n );\n --widget-text-name: max(\n 14px,\n calc(8.9px + 4.37 * var(--widget-unit)),\n calc(7.07 * var(--widget-unit))\n );\n --widget-text-meta: max(\n 11px,\n calc(8px + 2.44 * var(--widget-unit)),\n calc(4.88 * var(--widget-unit))\n );\n --widget-text-sub: max(\n 12px,\n calc(10.1px + 1.22 * var(--widget-unit)),\n calc(4.3 * var(--widget-unit))\n );\n --widget-text-caption: max(11px, calc(3.6 * var(--widget-unit)));\n --widget-control-h: max(36px, calc(30px + 3.84 * var(--widget-unit)));\n --widget-grid-pad: max(\n 10px,\n calc(1.2px + 5.64 * var(--widget-unit)),\n calc(6 * var(--widget-unit))\n );\n --widget-grid-gap: max(6px, calc(2.5px + 2.23 * var(--widget-unit)));\n --widget-icon-box: max(\n 44px,\n calc(31.3px + 8.14 * var(--widget-unit)),\n calc(17.7 * var(--widget-unit))\n );\n --widget-icon-glyph: max(\n 24px,\n calc(16px + 5.12 * var(--widget-unit)),\n calc(10 * var(--widget-unit))\n );\n --widget-pad: clamp(8px, 3.5cqb, 22px);\n --widget-gap: clamp(6px, 2cqb, 14px);\n --widget-title-size: clamp(12px, 2cqi, 18px);\n --widget-subtitle: clamp(12px, 2.5cqi, 20px);\n --widget-status-size: clamp(14px, 5cqi, 36px);\n --widget-value-size: clamp(18px, 7cqi, 48px);\n --widget-badge-size: clamp(11px, 1.6cqi, 14px);\n}\n\n/* Shell material: ui's .glass, worn through the class Widget.tsx carries.\n * Unlayered and class-specific, so these beat the formula's :where() defaults\n * (wash-2 is re-declared there and cannot be set from a utility). The tone\n * stays the formula's transparent default until Widget.tsx sets one inline:\n * a widget without a tone is the plain card, never a neutral-grey wash. */\n.glasshome-widget {\n --widget-wash: 22%;\n --widget-wash-2: 11%;\n --glass-wash: var(--widget-wash);\n /* The material's wash style: fade keeps --widget-wash-2, flat runs it up to --widget-wash. */\n --glass-wash-2: calc(\n var(--widget-wash-2) + (var(--widget-wash) - var(--widget-wash-2)) *\n (3 - var(--_material-wash-split, 3)) / 2\n );\n --glass-wash-angle: var(--_material-wash-angle, 135deg);\n --glass-base: color-mix(in srgb, var(--card) var(--material-clarity, 60%), transparent);\n --glass-rim: 0.3;\n --glass-lift: 0.45;\n --glass-shade: 0.05;\n --glass-grain: var(--_material-grain, none);\n --glass-halo: 1;\n backdrop-filter: var(--widget-backdrop, none);\n -webkit-backdrop-filter: var(--widget-backdrop, none);\n}\n/* The shell's outer glow, beside it so the glow can lie over neighbouring widgets. */\n.glasshome-widget-halo {\n --glass-lift: 0.45;\n}\n/* The material's fill: an accent wash on a widget that passes no tone of its own. */\n.glasshome-widget:not([data-toned]),\n.glasshome-widget-halo:not([data-toned]) {\n --glass-tone: color-mix(\n in srgb,\n var(--material-accent, var(--primary)) calc(var(--_material-fill, 0) * 100%),\n transparent\n );\n --glass-wash: 100%;\n --glass-wash-2: 50%;\n}\n/* A fill widget keeps a neutral card; the fill carries the tone, so a full fill is the toned card. */\n.glasshome-widget:has(.glasshome-widget-slider-fill) {\n --glass-wash: 0%;\n --glass-wash-2: 0%;\n}\n.dark .glasshome-widget {\n --glass-shade: 0;\n}\n/* Ink: the shell's line goes above every widget layer (they stack to 30), or full-bleed media buries it. */\n@container not style(--material-ink-level: 0) {\n .glasshome-widget::after {\n z-index: 40;\n }\n}\n\n/* === Slot: content layout === */\n/* Default: column. Flip to row only on wide-and-short widgets (matches the\n * old contentLayout heuristic: aspect > 1 AND height < 150px). */\n.glasshome-widget-content {\n position: relative;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n padding: var(--widget-pad);\n gap: var(--widget-gap);\n overflow: hidden;\n border-radius: var(--widget-radius);\n}\n@container widget (min-aspect-ratio: 1) and (max-height: 149px) {\n .glasshome-widget-content {\n flex-direction: row;\n align-items: center;\n justify-content: flex-start;\n }\n}\n\n/* === Compact 1×1 ===\n * Small in BOTH axes → stack the tile: icon on top, label + status centered\n * under it. Icon stays moderate (not a hero) so the text keeps room. Wide\n * tiles (2×1) fail the width test and keep the row layout above. Placed after\n * the row-flip so it wins. */\n@container widget (max-width: 189px) and (max-height: 189px) {\n .glasshome-widget-content {\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n gap: clamp(4px, 2.5cqmin, 8px);\n }\n .glasshome-widget-content > * {\n align-items: center;\n text-align: center;\n }\n .glasshome-widget-icon {\n --widget-icon-box: clamp(36px, 30cqmin, 56px);\n --widget-icon-glyph: clamp(20px, 17cqmin, 32px);\n }\n .glasshome-widget-title {\n font-size: clamp(11px, 6cqmin, 14px);\n max-width: 100%;\n }\n .glasshome-widget-status,\n .glasshome-widget-value {\n font-size: clamp(13px, 7cqmin, 17px);\n }\n .glasshome-widget-content [class*=\"ml-auto\"] {\n margin-left: 0 !important;\n }\n}\n.glasshome-widget-content [class*=\"ml-auto\"] {\n position: relative;\n z-index: 30;\n}\n\n/* === Slot: icon ===\n * ui's tinted icon pill (ICON_PILL_TINT): the disc is .glass, so the material shapes it. */\n.glasshome-widget-icon {\n width: var(--widget-icon-box);\n height: var(--widget-icon-box);\n border-radius: var(--radius-sm, 12px);\n --glass-tone: var(--widget-icon-color, var(--widget-color));\n --glass-rim: 0.4;\n --glass-wash: 18%;\n}\n.glasshome-widget-icon-glyph {\n font-size: var(--widget-icon-glyph);\n line-height: 1;\n}\n.glasshome-widget-icon-stack {\n --stack-step: calc(var(--widget-icon-box) * 0.12);\n position: absolute;\n /* The pill's border would otherwise shrink each plate and widen the first step. */\n inset: -1px;\n width: auto;\n height: auto;\n border-radius: var(--radius-sm, 12px);\n}\n.glasshome-widget-icon-stack-2 {\n translate: var(--stack-step) var(--stack-step);\n opacity: 0.45;\n z-index: -2;\n}\n.glasshome-widget-icon-stack-3 {\n translate: calc(2 * var(--stack-step)) calc(2 * var(--stack-step));\n opacity: 0.2;\n z-index: -3;\n}\n\n/* === Slot: text === */\n.glasshome-widget-title {\n font-size: var(--widget-title-size);\n line-height: 1.2;\n color: var(--color-muted-foreground, currentColor);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.glasshome-widget-subtitle {\n font-size: var(--widget-subtitle);\n color: var(--color-muted-foreground, currentColor);\n}\n.glasshome-widget-status {\n font-size: var(--widget-status-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.1;\n}\n.glasshome-widget-value {\n font-size: var(--widget-value-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.05;\n}\n.glasshome-widget-badge {\n font-size: var(--widget-badge-size);\n font-weight: 500;\n padding: 0.125rem 0.5rem;\n border-radius: 9999px;\n background: color-mix(in oklch, var(--color-foreground, currentColor) 20%, transparent);\n color: var(--color-foreground, currentColor);\n}\n\n.glasshome-widget-loading {\n background: color-mix(in oklch, var(--widget-color) 20%, transparent);\n}\n\n/* === Slider fill ===\n * Value flows in via --widget-fill-value (0-100). Vertical orientation auto-\n * detected via container query. */\n.glasshome-widget-slider-fill {\n --widget-fill-value: 0;\n background: linear-gradient(\n 135deg,\n color-mix(\n in srgb,\n var(--widget-color) calc(var(--widget-wash) * var(--material-tint, 1)),\n transparent\n ),\n color-mix(\n in srgb,\n var(--widget-color-to, var(--widget-color))\n calc(var(--widget-wash-2) * var(--material-tint, 1)),\n transparent\n )\n );\n /* Inset: the clip-path cuts any outer shadow. */\n box-shadow: inset 0 0 calc(var(--material-glow, 0px) * 1.2)\n oklch(from var(--widget-color) l c h / 0.55);\n clip-path: inset(0 calc((100 - var(--widget-fill-value)) * 1%) 0 0 round var(--widget-radius));\n}\n@container widget (max-aspect-ratio: 1) {\n .glasshome-widget-slider-fill {\n clip-path: inset(calc((100 - var(--widget-fill-value)) * 1%) 0 0 0 round var(--widget-radius));\n }\n}\n\n/* === Anatomy: Widget.Content with a Widget.Head lays its parts out as a tile === */\n.glasshome-widget-grid {\n position: relative;\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr) auto;\n gap: var(--widget-grid-gap);\n height: 100%;\n padding: var(--widget-grid-pad);\n overflow: hidden;\n isolation: isolate;\n color: var(--foreground);\n}\n\n/* In-flow content spans the tile (the max-content first column would collapse it); absolute parts keep the padding box. */\n.glasshome-widget-grid\n > :where(:not(.glasshome-widget-backdrop, .glasshome-widget-layer, .glasshome-widget-glyph)) {\n grid-column: 1 / -1;\n}\n.glasshome-widget-layer {\n position: absolute;\n inset: 0;\n z-index: -1;\n overflow: hidden;\n}\n.glasshome-widget-head {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n}\n.glasshome-widget-head-text {\n min-height: var(--widget-icon-box);\n justify-content: center;\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n flex: 1;\n}\n.glasshome-widget-head-aside {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: 6px;\n max-height: 26px;\n overflow: hidden;\n flex-shrink: 1;\n}\n.glasshome-widget-eyebrow {\n font-size: var(--widget-text-meta);\n font-weight: 500;\n line-height: 1.25;\n color: var(--muted-foreground);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.glasshome-widget-name {\n font-size: var(--widget-text-name);\n font-weight: 650;\n line-height: 1.2;\n letter-spacing: -0.01em;\n color: var(--foreground);\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow: hidden;\n overflow-wrap: break-word;\n}\n\n.glasshome-widget-hero {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n gap: var(--widget-grid-gap);\n min-height: 0;\n min-width: 0;\n}\n.glasshome-widget-reading {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n z-index: 1;\n}\n.glasshome-widget-reading-value {\n font-size: var(--widget-text-value);\n font-weight: 650;\n line-height: 1;\n letter-spacing: -0.03em;\n font-variant-numeric: tabular-nums;\n color: var(--foreground);\n white-space: nowrap;\n}\n/* Alternating names restart the rise on each change without rebuilding the text. */\n.glasshome-widget-reading-value[data-turn=\"a\"] {\n animation: tile-value-in-a var(--duration-morph) var(--ease-morph);\n}\n.glasshome-widget-reading-value[data-turn=\"b\"] {\n animation: tile-value-in-b var(--duration-morph) var(--ease-morph);\n}\n@keyframes tile-value-in-a {\n from {\n opacity: 0;\n transform: translateY(0.25em);\n }\n}\n@keyframes tile-value-in-b {\n from {\n opacity: 0;\n transform: translateY(0.25em);\n }\n}\n.glasshome-widget-unit {\n font-size: 0.5em;\n font-weight: 550;\n letter-spacing: 0;\n margin-left: 0.08em;\n color: var(--muted-foreground);\n}\n.glasshome-widget-sub {\n font-size: var(--widget-text-sub);\n font-weight: 500;\n color: var(--muted-foreground);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Placed on the tile, not the hero, so a control row never moves or shrinks it. */\n.glasshome-widget-art {\n position: absolute;\n right: var(--widget-grid-pad);\n bottom: var(--widget-grid-pad);\n height: min(\n calc(100% - 2 * var(--widget-grid-pad) - var(--widget-icon-box) - var(--widget-grid-gap)),\n 48cqi\n );\n display: flex;\n align-items: flex-end;\n justify-content: flex-end;\n pointer-events: none;\n}\n/* Beside art a long word (\"Unlocked\") shrinks to end where the art starts, at about 50cqi; short values keep full size. */\n@container widget (min-width: 180px) and (min-height: 130px) {\n .glasshome-widget-hero[data-art] .glasshome-widget-reading-value {\n font-size: max(18px, min(var(--widget-text-value), calc(50cqi / (var(--value-len, 1) * 0.56))));\n }\n}\n.glasshome-widget-backdrop > img {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n/* Art keeps its shape and clears a state word at its largest (15cqi, about 3.4em); each art sets --art-aspect. */\n.glasshome-widget-grid .glasshome-widget-art > * {\n height: min(\n 100%,\n calc((52cqi - 2 * var(--widget-grid-pad) - var(--widget-grid-gap)) / var(--art-aspect, 1))\n );\n flex-shrink: 0;\n}\n.glasshome-widget-grid .glasshome-widget-art > img {\n width: auto;\n height: auto;\n max-height: 100%;\n max-width: calc(52cqi - 2 * var(--widget-grid-pad) - var(--widget-grid-gap));\n}\n\n.glasshome-widget-controls {\n display: flex;\n gap: 8px;\n min-width: 0;\n}\n\n.glasshome-widget-glyph {\n display: none;\n position: absolute;\n right: -8%;\n bottom: -22%;\n font-size: min(130cqb, 80cqi);\n line-height: 1;\n color: var(--widget-color);\n opacity: 0.16;\n pointer-events: none;\n z-index: -1;\n}\n\n/* Controls sit on the bottom row beside the value, or under it on a narrow tile; the art lifts above them. */\n.glasshome-widget-head {\n grid-column: 1 / -1;\n}\n.glasshome-widget-hero {\n grid-row: 3;\n grid-column: 1 / -1;\n}\n.glasshome-widget-grid:has(> .glasshome-widget-controls) > .glasshome-widget-hero {\n grid-column: 1;\n}\n.glasshome-widget-controls {\n grid-row: 3;\n grid-column: 2;\n align-self: end;\n position: relative;\n z-index: 1;\n}\n.glasshome-widget-grid:has(> .glasshome-widget-hero[data-empty]) > .glasshome-widget-controls {\n grid-column: 1 / -1;\n}\n@container widget (max-width: 519px) {\n .glasshome-widget-grid:has(> .glasshome-widget-controls) {\n grid-template-rows: auto minmax(0, 1fr) auto auto;\n }\n .glasshome-widget-grid:has(> .glasshome-widget-controls) > .glasshome-widget-hero {\n grid-column: 1 / -1;\n }\n .glasshome-widget-controls {\n grid-row: 4;\n grid-column: 1 / -1;\n }\n .glasshome-widget-grid:has(> .glasshome-widget-controls) .glasshome-widget-art {\n bottom: calc(var(--widget-grid-pad) + var(--widget-control-h) + var(--widget-grid-gap));\n height: min(\n calc(\n 100% - 2 * var(--widget-grid-pad) - var(--widget-icon-box) - 2 * var(--widget-grid-gap) -\n var(--widget-control-h)\n ),\n 48cqi\n );\n }\n}\n@container widget (max-height: 229px) {\n .glasshome-widget-controls {\n display: none;\n }\n .glasshome-widget-grid:has(> .glasshome-widget-controls) {\n grid-template-rows: auto minmax(0, 1fr) auto;\n }\n .glasshome-widget-grid:has(> .glasshome-widget-controls) .glasshome-widget-art {\n bottom: var(--widget-grid-pad);\n height: min(\n calc(100% - 2 * var(--widget-grid-pad) - var(--widget-icon-box) - var(--widget-grid-gap)),\n 48cqi\n );\n }\n}\n@container widget (max-width: 179px) {\n .glasshome-widget-art {\n display: none;\n }\n}\n@container widget (max-height: 169px) {\n .glasshome-widget-head-aside {\n display: none;\n }\n}\n@container widget ((max-height: 129px) or (max-width: 139px)) {\n .glasshome-widget-head-text {\n min-height: 0;\n }\n .glasshome-widget-name {\n -webkit-line-clamp: 1;\n }\n .glasshome-widget-grid {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n gap: 2px;\n }\n .glasshome-widget-head-icon,\n .glasshome-widget-art,\n .glasshome-widget-eyebrow,\n .glasshome-widget-sub {\n display: none;\n }\n .glasshome-widget-glyph {\n display: block;\n }\n .glasshome-widget-reading-value {\n font-size: clamp(18px, min(34cqb, 20cqi), 30px);\n }\n .glasshome-widget-name {\n font-size: clamp(12px, min(18cqb, 11cqi), 15px);\n font-weight: 550;\n color: var(--muted-foreground);\n }\n}\n@container widget (max-height: 129px) and (min-width: 260px) {\n .glasshome-widget-grid {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n gap: var(--widget-grid-gap);\n }\n .glasshome-widget-name {\n font-size: clamp(14px, 22cqb, 18px);\n font-weight: 650;\n color: var(--foreground);\n }\n .glasshome-widget-eyebrow {\n display: block;\n }\n}\n\n.glasshome-widget-backdrop {\n position: absolute;\n inset: 0;\n z-index: -2;\n overflow: hidden;\n}\n.glasshome-widget-backdrop > img.area-night {\n opacity: 0;\n transition: opacity 700ms ease;\n}\n.glasshome-widget-backdrop > img.area-night[data-visible] {\n opacity: 1;\n}\n.glasshome-widget-backdrop > .glasshome-widget-backdrop-light {\n position: absolute;\n inset: 0;\n background: radial-gradient(90% 80% at 25% 30%, oklch(0.8 0.14 70), transparent 70%);\n mix-blend-mode: soft-light;\n opacity: var(--backdrop-light, 0);\n transition: opacity 500ms ease;\n}\n.glasshome-widget-backdrop::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background: linear-gradient(\n to bottom,\n color-mix(in oklch, var(--card) 82%, transparent) 0%,\n color-mix(in oklch, var(--card) 40%, transparent) 22%,\n transparent 42%,\n transparent 62%,\n color-mix(in oklch, var(--card) 45%, transparent) 82%,\n color-mix(in oklch, var(--card) 80%, transparent) 100%\n );\n}\n\n@container widget (max-width: 239px) {\n .glasshome-widget-choice [data-optional] {\n display: none;\n }\n}\n@container widget (max-width: 259px) {\n .glasshome-widget-head-aside {\n display: none;\n }\n}\n@container widget (max-width: 139px) {\n .glasshome-widget-controls {\n display: none;\n }\n}\n\n.glasshome-widget-controls {\n justify-content: flex-start;\n align-items: center;\n}\n.glasshome-widget-control.glasshome-widget-control {\n width: var(--widget-control-h);\n height: var(--widget-control-h);\n}\n.glasshome-widget-choice .glasshome-widget-control.glasshome-widget-control {\n width: calc(var(--widget-control-h) - 8px);\n height: calc(var(--widget-control-h) - 8px);\n}\n@container widget (max-width: 179px) and (min-height: 130px) {\n .glasshome-widget-grid:not(:has(> .glasshome-widget-backdrop)) .glasshome-widget-head-text {\n min-height: 0;\n }\n .glasshome-widget-grid:not(:has(> .glasshome-widget-backdrop)) .glasshome-widget-head {\n flex-direction: column;\n gap: 6px;\n }\n}\n.glasshome-widget-unit[data-degree] {\n vertical-align: top;\n margin-left: 0.02em;\n color: var(--foreground);\n}\n.glasshome-widget-control-wide.glasshome-widget-control-wide {\n height: var(--widget-control-h);\n gap: 6px;\n padding: 0 14px;\n}\n@container widget (max-width: 179px) {\n .glasshome-widget-grid:has(> .glasshome-widget-backdrop) .glasshome-widget-head-icon {\n display: none;\n }\n}\n.glasshome-widget-grid:has(> .glasshome-widget-backdrop)\n :is(\n .glasshome-widget-reading-value,\n .glasshome-widget-sub,\n .glasshome-widget-name,\n .glasshome-widget-eyebrow\n ) {\n text-shadow: 0 1px 8px color-mix(in oklch, var(--card) 75%, transparent);\n}\n.glasshome-widget-grid:has(> .glasshome-widget-backdrop)\n :is(.glasshome-widget-sub, .glasshome-widget-eyebrow) {\n color: color-mix(in oklch, var(--foreground) 82%, transparent);\n}\n/* Control glyphs and words keep their share of a control as it grows past 4x4. */\n.glasshome-widget-grid\n :is(.glasshome-widget-control, .glasshome-widget-control-wide)\n :is(iconify-icon, svg) {\n font-size: calc(var(--widget-control-h) * 0.43);\n width: 1em;\n height: 1em;\n}\n:is(.glasshome-widget-controls, .glasshome-widget-control-wide) {\n font-size: max(13px, calc(var(--widget-control-h) * 0.3));\n}\n/* A big tile with no art of its own carries its icon large and faint, so the glass is not an empty box. */\n@container widget (min-width: 300px) and (min-height: 260px) {\n .glasshome-widget-grid:not(\n :has(> .glasshome-widget-backdrop),\n :has(> .glasshome-widget-hero[data-art], > .glasshome-widget-art, > .glasshome-widget-layer)\n )\n > .glasshome-widget-glyph {\n display: block;\n right: -3%;\n bottom: -12%;\n font-size: min(78cqb, 52cqi);\n opacity: 0.1;\n }\n}\n/* A one-shot action confirms on its control and on the glyph, the one thing a compact tile shows. */\n.glasshome-widget-grid > .glasshome-widget-glyph {\n transition: opacity var(--duration-state) var(--ease-morph);\n}\n.glasshome-widget[data-confirmed] .glasshome-widget-glyph {\n opacity: 0.5;\n}\n.glasshome-widget-grid\n [data-confirmed]:is(.glasshome-widget-control, .glasshome-widget-control-wide) {\n --glass-base: color-mix(in srgb, var(--widget-color) 35%, transparent);\n transition: background-color var(--duration-state) var(--ease-morph);\n}\n\n/* === Sheet: what a held tile opens (framework/panel) ===\n * Rendered in a popover or dialog outside the widget's shadow root, so every rule\n * the sheet needs lives here, never in a widget's own utilities. */\n.glasshome-sheet {\n display: flex;\n flex-direction: column;\n gap: 18px;\n color: var(--foreground);\n}\n.glasshome-sheet [data-slot=\"swatch-picker\"] {\n max-width: 360px;\n}\n.glasshome-panel-section {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.glasshome-panel-label {\n margin: 0;\n font-size: 13px;\n font-weight: 500;\n color: var(--muted-foreground);\n}\n.glasshome-panel-rows {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 8px;\n}\n.glasshome-panel-row-wrap {\n position: relative;\n min-width: 0;\n}\n.glasshome-panel-row {\n --widget-wash: 22%;\n --widget-wash-2: 11%;\n --widget-radius: var(--radius-lg, 16px);\n --widget-icon-box: 34px;\n --widget-icon-glyph: 19px;\n position: relative;\n width: 100%;\n height: 56px;\n justify-content: flex-start;\n gap: 10px;\n padding: 0 12px 0 10px;\n overflow: hidden;\n text-align: left;\n touch-action: pan-y;\n}\n.glasshome-panel-row-static {\n cursor: default;\n scale: none;\n}\n.glasshome-panel-row-fill {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n.glasshome-panel-row-icon {\n position: relative;\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n}\n.glasshome-panel-row-icon-off {\n color: var(--muted-foreground);\n}\n.glasshome-panel-row-text {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n.glasshome-panel-row-name,\n.glasshome-panel-row-state,\n.glasshome-panel-fact-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n/* A reading may take a second line rather than lose its end (\"3 Moderate\"). */\n.glasshome-panel-fact-value {\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n}\n.glasshome-panel-row-name,\n.glasshome-panel-fact-value {\n font-size: 14px;\n font-weight: 500;\n color: var(--foreground);\n}\n.glasshome-panel-row-state,\n.glasshome-panel-fact-label {\n font-size: 12px;\n font-weight: 400;\n color: var(--muted-foreground);\n}\n.glasshome-panel-row-trailing {\n position: absolute;\n top: 50%;\n right: 10px;\n translate: 0 -50%;\n}\n.glasshome-panel-facts {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));\n row-gap: 10px;\n padding: 10px 4px 10px 0;\n overflow: hidden;\n border-radius: var(--radius-lg, 16px);\n --glass-base: color-mix(in srgb, var(--card) var(--material-clarity, 60%), transparent);\n backdrop-filter: blur(calc(var(--material-blur, 24px) * 0.6)) saturate(1.6);\n -webkit-backdrop-filter: blur(calc(var(--material-blur, 24px) * 0.6)) saturate(1.6);\n}\n/* Without blur a see-through strip is just see-through: it takes the card fill. */\n.reduce-blur .glasshome-panel-facts {\n --glass-base: var(--card);\n}\n.glasshome-panel-fact {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 8px;\n padding: 0 12px;\n box-shadow: -1px 0 0 color-mix(in oklch, var(--foreground) 10%, transparent);\n}\n.glasshome-panel-fact-icon {\n flex-shrink: 0;\n font-size: 18px;\n color: var(--muted-foreground);\n}\n\n/* Inset: the grid cell clips anything drawn outside the tile. */\n.glasshome-widget:focus-visible {\n outline: 2px solid var(--ring);\n outline-offset: -2px;\n}\n\n/* === Hold flood: the dock's hold fill (ui HOLD_MOTION), grown from the finger === */\n.glasshome-widget-hold-flood {\n position: absolute;\n translate: -50% -50%;\n border-radius: 9999px;\n background: color-mix(in oklch, var(--primary) 45%, transparent);\n pointer-events: none;\n scale: 0;\n opacity: 0;\n transition:\n scale var(--duration-state, 200ms) var(--ease-contract, ease-in),\n opacity var(--duration-state, 200ms) var(--ease-contract, ease-in);\n}\n.glasshome-widget-hold-flood[data-hold] {\n scale: 1;\n opacity: 1;\n transition-duration: var(--duration-hold, 250ms);\n transition-timing-function: linear;\n}\n.glasshome-widget-hold-flood[data-fired] {\n scale: 1;\n opacity: 0;\n}\n/* A row of ui buttons in a sheet (scenes, one-tap actions). */\n.glasshome-sheet-actions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n/* The sheet wears its tile: the tile's tone washed into the glass, its picture as a band behind\n the head that fades into the glass, so the tile reads as having grown open. */\n.glasshome-sheet-surface {\n --glass-wash: 20%;\n --glass-wash-2: 7%;\n --widget-icon-box: 48px;\n --widget-icon-glyph: 26px;\n}\n.glasshome-sheet-band {\n position: absolute;\n inset: 0 0 auto;\n height: 150px;\n overflow: hidden;\n pointer-events: none;\n mask-image: linear-gradient(180deg, #000 30%, transparent);\n}\n.glasshome-sheet-band > img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n opacity: 0.55;\n}\n.glasshome-sheet-surface > [data-slot$=\"-header\"],\n.glasshome-sheet-surface > [data-slot$=\"-body\"] {\n position: relative;\n}\n.glasshome-sheet-icon {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n", sr = !1, cr, lr = /* @__PURE__ */ new WeakSet();
712
- function ur() {
713
- return cr || (cr = new CSSStyleSheet(), cr.replaceSync(or.replace(/:root\b/g, ":host").replace(/^\.dark\b/gm, ":host(.dark)"))), cr;
699
+ var ur = "/* Authoritative SDK CSS contract. Injected once on first Widget mount\n * via framework/theming/tokens.ts.\n *\n * All widget-internal visual scale is driven from CSS custom properties +\n * container queries on the `.glasshome-widget` shell (`container-type: size`).\n * No JS classifier, no size tier enum.\n */\n\n:root {\n --tone-success: oklch(0.7 0.18 145);\n --tone-warning: oklch(0.8 0.17 75);\n --tone-danger: oklch(0.64 0.22 27);\n --tone-info: oklch(0.66 0.2 245);\n --tone-neutral: oklch(0.65 0.02 250);\n --tone-accent: oklch(0.74 0.18 60);\n\n --widget-glow-default: 0.4;\n}\n\n.dark {\n --tone-success: oklch(0.74 0.18 145);\n --tone-warning: oklch(0.82 0.17 75);\n --tone-danger: oklch(0.68 0.22 27);\n --tone-info: oklch(0.7 0.2 245);\n --tone-neutral: oklch(0.69 0.02 250);\n --tone-accent: oklch(0.78 0.18 60);\n\n --widget-glow-default: 0.5;\n}\n\n@property --widget-color {\n syntax: \"<color>\";\n inherits: true;\n initial-value: oklch(0.65 0.02 250);\n}\n\n/* === Widget shell ===\n * One scale: --widget-unit is 1% of the shell's short side. Each size is a floor,\n * a line through the designed 2x2 and 4x4 sizes, and past 4x4 the share it has\n * at 4x4. A widget sizes its own text with these tokens and scales with every tile. */\n.glasshome-widget {\n --widget-color: var(--tone-neutral);\n --widget-glow-strength: var(--widget-glow-default);\n --widget-radius: var(--radius-xl, 12px);\n\n --widget-unit: 1cqmin;\n --widget-text-value: max(\n 22px,\n calc(8.5px + 13.4 * var(--widget-unit)),\n calc(16 * var(--widget-unit))\n );\n --widget-text-name: max(\n 14px,\n calc(8.9px + 4.37 * var(--widget-unit)),\n calc(7.07 * var(--widget-unit))\n );\n --widget-text-meta: max(\n 11px,\n calc(8px + 2.44 * var(--widget-unit)),\n calc(4.88 * var(--widget-unit))\n );\n --widget-text-sub: max(\n 12px,\n calc(10.1px + 1.22 * var(--widget-unit)),\n calc(4.3 * var(--widget-unit))\n );\n --widget-text-caption: max(11px, calc(3.6 * var(--widget-unit)));\n --widget-control-h: max(36px, calc(30px + 3.84 * var(--widget-unit)));\n --widget-grid-pad: max(\n 10px,\n calc(1.2px + 5.64 * var(--widget-unit)),\n calc(6 * var(--widget-unit))\n );\n --widget-grid-gap: max(6px, calc(2.5px + 2.23 * var(--widget-unit)));\n --widget-icon-box: max(\n 44px,\n calc(31.3px + 8.14 * var(--widget-unit)),\n calc(17.7 * var(--widget-unit))\n );\n --widget-icon-glyph: max(\n 24px,\n calc(16px + 5.12 * var(--widget-unit)),\n calc(10 * var(--widget-unit))\n );\n --widget-pad: clamp(8px, 3.5cqb, 22px);\n --widget-gap: clamp(6px, 2cqb, 14px);\n --widget-title-size: clamp(12px, 2cqi, 18px);\n --widget-subtitle: clamp(12px, 2.5cqi, 20px);\n --widget-status-size: clamp(14px, 5cqi, 36px);\n --widget-value-size: clamp(18px, 7cqi, 48px);\n --widget-badge-size: clamp(11px, 1.6cqi, 14px);\n}\n\n/* Shell material: ui's .glass, worn through the class Widget.tsx carries.\n * Unlayered and class-specific, so these beat the formula's :where() defaults\n * (wash-2 is re-declared there and cannot be set from a utility). The tone\n * stays the formula's transparent default until Widget.tsx sets one inline:\n * a widget without a tone is the plain card, never a neutral-grey wash. */\n.glasshome-widget {\n --widget-wash: 22%;\n --widget-wash-2: 11%;\n --glass-wash: var(--widget-wash);\n /* The material's wash style: fade keeps --widget-wash-2, flat runs it up to --widget-wash. */\n --glass-wash-2: calc(\n var(--widget-wash-2) + (var(--widget-wash) - var(--widget-wash-2)) *\n (3 - var(--_material-wash-split, 3)) / 2\n );\n --glass-wash-angle: var(--_material-wash-angle, 135deg);\n --glass-base: color-mix(in srgb, var(--card) var(--material-clarity, 60%), transparent);\n --glass-rim: 0.3;\n --glass-lift: 0.45;\n --glass-shade: 0.05;\n --glass-grain: var(--_material-grain, none);\n --glass-halo: 1;\n backdrop-filter: var(--widget-backdrop, none);\n -webkit-backdrop-filter: var(--widget-backdrop, none);\n}\n/* The shell's outer glow, beside it so the glow can lie over neighbouring widgets. */\n.glasshome-widget-halo {\n --glass-lift: 0.45;\n}\n/* The material's fill: an accent wash on a widget that passes no tone of its own. */\n.glasshome-widget:not([data-toned]),\n.glasshome-widget-halo:not([data-toned]) {\n --glass-tone: color-mix(\n in srgb,\n var(--material-accent, var(--primary)) calc(var(--_material-fill, 0) * 100%),\n transparent\n );\n --glass-wash: 100%;\n --glass-wash-2: 50%;\n}\n/* A fill widget keeps a neutral card; the fill carries the tone, so a full fill is the toned card. */\n.glasshome-widget:has(.glasshome-widget-slider-fill) {\n --glass-wash: 0%;\n --glass-wash-2: 0%;\n}\n.dark .glasshome-widget {\n --glass-shade: 0;\n}\n/* Ink: the shell's line goes above every widget layer (they stack to 30), or full-bleed media buries it. */\n@container not style(--material-ink-level: 0) {\n .glasshome-widget::after {\n z-index: 40;\n }\n}\n\n/* === Slot: content layout === */\n/* Default: column. Flip to row only on wide-and-short widgets (matches the\n * old contentLayout heuristic: aspect > 1 AND height < 150px). */\n.glasshome-widget-content {\n position: relative;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n padding: var(--widget-pad);\n gap: var(--widget-gap);\n overflow: hidden;\n border-radius: var(--widget-radius);\n}\n@container widget (min-aspect-ratio: 1) and (max-height: 149px) {\n .glasshome-widget-content {\n flex-direction: row;\n align-items: center;\n justify-content: flex-start;\n }\n}\n\n/* === Compact 1×1 ===\n * Small in BOTH axes → stack the tile: icon on top, label + status centered\n * under it. Icon stays moderate (not a hero) so the text keeps room. Wide\n * tiles (2×1) fail the width test and keep the row layout above. Placed after\n * the row-flip so it wins. */\n@container widget (max-width: 189px) and (max-height: 189px) {\n .glasshome-widget-content {\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n gap: clamp(4px, 2.5cqmin, 8px);\n }\n .glasshome-widget-content > * {\n align-items: center;\n text-align: center;\n }\n .glasshome-widget-icon {\n --widget-icon-box: clamp(36px, 30cqmin, 56px);\n --widget-icon-glyph: clamp(20px, 17cqmin, 32px);\n }\n .glasshome-widget-title {\n font-size: clamp(11px, 6cqmin, 14px);\n max-width: 100%;\n }\n .glasshome-widget-status,\n .glasshome-widget-value {\n font-size: clamp(13px, 7cqmin, 17px);\n }\n .glasshome-widget-content [class*=\"ml-auto\"] {\n margin-left: 0 !important;\n }\n}\n.glasshome-widget-content [class*=\"ml-auto\"] {\n position: relative;\n z-index: 30;\n}\n\n/* === Slot: icon ===\n * ui's tinted icon pill (ICON_PILL_TINT): the disc is .glass, so the material shapes it. */\n.glasshome-widget-icon {\n width: var(--widget-icon-box);\n height: var(--widget-icon-box);\n border-radius: var(--radius-sm, 12px);\n --glass-tone: var(--widget-icon-color, var(--widget-color));\n --glass-rim: 0.4;\n --glass-wash: 18%;\n}\n.glasshome-widget-icon-glyph {\n font-size: var(--widget-icon-glyph);\n line-height: 1;\n}\n.glasshome-widget-icon-stack {\n --stack-step: calc(var(--widget-icon-box) * 0.12);\n position: absolute;\n /* The pill's border would otherwise shrink each plate and widen the first step. */\n inset: -1px;\n width: auto;\n height: auto;\n border-radius: var(--radius-sm, 12px);\n}\n.glasshome-widget-icon-stack-2 {\n translate: var(--stack-step) var(--stack-step);\n opacity: 0.45;\n z-index: -2;\n}\n.glasshome-widget-icon-stack-3 {\n translate: calc(2 * var(--stack-step)) calc(2 * var(--stack-step));\n opacity: 0.2;\n z-index: -3;\n}\n\n/* === Slot: text === */\n.glasshome-widget-title {\n font-size: var(--widget-title-size);\n line-height: 1.2;\n color: var(--color-muted-foreground, currentColor);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.glasshome-widget-subtitle {\n font-size: var(--widget-subtitle);\n color: var(--color-muted-foreground, currentColor);\n}\n.glasshome-widget-status {\n font-size: var(--widget-status-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.1;\n}\n.glasshome-widget-value {\n font-size: var(--widget-value-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.05;\n}\n.glasshome-widget-badge {\n font-size: var(--widget-badge-size);\n font-weight: 500;\n padding: 0.125rem 0.5rem;\n border-radius: 9999px;\n background: color-mix(in oklch, var(--color-foreground, currentColor) 20%, transparent);\n color: var(--color-foreground, currentColor);\n}\n\n.glasshome-widget-loading {\n background: color-mix(in oklch, var(--widget-color) 20%, transparent);\n}\n\n/* === Slider fill ===\n * Value flows in via --widget-fill-value (0-100). Vertical orientation auto-\n * detected via container query. */\n.glasshome-widget-slider-fill {\n --widget-fill-value: 0;\n background: linear-gradient(\n 135deg,\n color-mix(\n in srgb,\n var(--widget-color) calc(var(--widget-wash) * var(--material-tint, 1)),\n transparent\n ),\n color-mix(\n in srgb,\n var(--widget-color-to, var(--widget-color))\n calc(var(--widget-wash-2) * var(--material-tint, 1)),\n transparent\n )\n );\n /* Inset: the clip-path cuts any outer shadow. */\n box-shadow: inset 0 0 calc(var(--material-glow, 0px) * 1.2)\n oklch(from var(--widget-color) l c h / 0.55);\n clip-path: inset(0 calc((100 - var(--widget-fill-value)) * 1%) 0 0 round var(--widget-radius));\n}\n@container widget (max-aspect-ratio: 1) {\n .glasshome-widget-slider-fill {\n clip-path: inset(calc((100 - var(--widget-fill-value)) * 1%) 0 0 0 round var(--widget-radius));\n }\n}\n\n/* === Anatomy: Widget.Content with a Widget.Head lays its parts out as a tile === */\n.glasshome-widget-grid {\n position: relative;\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr) auto;\n gap: var(--widget-grid-gap);\n height: 100%;\n padding: var(--widget-grid-pad);\n overflow: hidden;\n isolation: isolate;\n color: var(--foreground);\n}\n\n/* In-flow content spans the tile (the max-content first column would collapse it); absolute parts keep the padding box. */\n.glasshome-widget-grid\n > :where(:not(.glasshome-widget-backdrop, .glasshome-widget-layer, .glasshome-widget-glyph)) {\n grid-column: 1 / -1;\n}\n.glasshome-widget-layer {\n position: absolute;\n inset: 0;\n z-index: -1;\n overflow: hidden;\n}\n.glasshome-widget-head {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n}\n.glasshome-widget-head-text {\n min-height: var(--widget-icon-box);\n justify-content: center;\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n flex: 1;\n}\n.glasshome-widget-head-aside {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: 6px;\n max-height: 26px;\n overflow: hidden;\n flex-shrink: 1;\n}\n.glasshome-widget-eyebrow {\n font-size: var(--widget-text-meta);\n font-weight: 500;\n line-height: 1.25;\n color: var(--muted-foreground);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.glasshome-widget-name {\n font-size: var(--widget-text-name);\n font-weight: 650;\n line-height: 1.2;\n letter-spacing: -0.01em;\n color: var(--foreground);\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow: hidden;\n overflow-wrap: break-word;\n}\n\n.glasshome-widget-hero {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n gap: var(--widget-grid-gap);\n min-height: 0;\n min-width: 0;\n}\n.glasshome-widget-reading {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n z-index: 1;\n}\n.glasshome-widget-reading-value {\n font-size: var(--widget-text-value);\n font-weight: 650;\n line-height: 1;\n letter-spacing: -0.03em;\n font-variant-numeric: tabular-nums;\n color: var(--foreground);\n white-space: nowrap;\n}\n/* Alternating names restart the rise on each change without rebuilding the text. */\n.glasshome-widget-reading-value[data-turn=\"a\"] {\n animation: tile-value-in-a var(--duration-morph) var(--ease-morph);\n}\n.glasshome-widget-reading-value[data-turn=\"b\"] {\n animation: tile-value-in-b var(--duration-morph) var(--ease-morph);\n}\n@keyframes tile-value-in-a {\n from {\n opacity: 0;\n transform: translateY(0.25em);\n }\n}\n@keyframes tile-value-in-b {\n from {\n opacity: 0;\n transform: translateY(0.25em);\n }\n}\n.glasshome-widget-unit {\n font-size: 0.5em;\n font-weight: 550;\n letter-spacing: 0;\n margin-left: 0.08em;\n color: var(--muted-foreground);\n}\n.glasshome-widget-sub {\n font-size: var(--widget-text-sub);\n font-weight: 500;\n color: var(--muted-foreground);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Placed on the tile, not the hero, so a control row never moves or shrinks it. */\n.glasshome-widget-art {\n position: absolute;\n right: var(--widget-grid-pad);\n bottom: var(--widget-grid-pad);\n height: min(\n calc(100% - 2 * var(--widget-grid-pad) - var(--widget-icon-box) - var(--widget-grid-gap)),\n 48cqi\n );\n display: flex;\n align-items: flex-end;\n justify-content: flex-end;\n pointer-events: none;\n}\n/* Beside art a long word (\"Unlocked\") shrinks to end where the art starts, at about 50cqi; short values keep full size. */\n@container widget (min-width: 180px) and (min-height: 130px) {\n .glasshome-widget-hero[data-art] .glasshome-widget-reading-value {\n font-size: max(18px, min(var(--widget-text-value), calc(50cqi / (var(--value-len, 1) * 0.56))));\n }\n}\n.glasshome-widget-backdrop > img {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n/* Art keeps its shape and clears a state word at its largest (15cqi, about 3.4em); each art sets --art-aspect. */\n.glasshome-widget-grid .glasshome-widget-art > * {\n height: min(\n 100%,\n calc((52cqi - 2 * var(--widget-grid-pad) - var(--widget-grid-gap)) / var(--art-aspect, 1))\n );\n flex-shrink: 0;\n}\n.glasshome-widget-grid .glasshome-widget-art > img {\n width: auto;\n height: auto;\n max-height: 100%;\n max-width: calc(52cqi - 2 * var(--widget-grid-pad) - var(--widget-grid-gap));\n}\n\n.glasshome-widget-controls {\n display: flex;\n gap: 8px;\n min-width: 0;\n}\n\n.glasshome-widget-glyph {\n display: none;\n position: absolute;\n right: -8%;\n bottom: -22%;\n font-size: min(130cqb, 80cqi);\n line-height: 1;\n color: var(--widget-color);\n opacity: 0.16;\n pointer-events: none;\n z-index: -1;\n}\n\n/* Controls sit on the bottom row beside the value, or under it on a narrow tile; the art lifts above them. */\n.glasshome-widget-head {\n grid-column: 1 / -1;\n}\n.glasshome-widget-hero {\n grid-row: 3;\n grid-column: 1 / -1;\n}\n.glasshome-widget-grid:has(> .glasshome-widget-controls) > .glasshome-widget-hero {\n grid-column: 1;\n}\n.glasshome-widget-controls {\n grid-row: 3;\n grid-column: 2;\n align-self: end;\n position: relative;\n z-index: 1;\n}\n.glasshome-widget-grid:has(> .glasshome-widget-hero[data-empty]) > .glasshome-widget-controls {\n grid-column: 1 / -1;\n}\n@container widget (max-width: 519px) {\n .glasshome-widget-grid:has(> .glasshome-widget-controls) {\n grid-template-rows: auto minmax(0, 1fr) auto auto;\n }\n .glasshome-widget-grid:has(> .glasshome-widget-controls) > .glasshome-widget-hero {\n grid-column: 1 / -1;\n }\n .glasshome-widget-controls {\n grid-row: 4;\n grid-column: 1 / -1;\n }\n .glasshome-widget-grid:has(> .glasshome-widget-controls) .glasshome-widget-art {\n bottom: calc(var(--widget-grid-pad) + var(--widget-control-h) + var(--widget-grid-gap));\n height: min(\n calc(\n 100% - 2 * var(--widget-grid-pad) - var(--widget-icon-box) - 2 * var(--widget-grid-gap) -\n var(--widget-control-h)\n ),\n 48cqi\n );\n }\n}\n@container widget (max-height: 229px) {\n .glasshome-widget-controls {\n display: none;\n }\n .glasshome-widget-grid:has(> .glasshome-widget-controls) {\n grid-template-rows: auto minmax(0, 1fr) auto;\n }\n .glasshome-widget-grid:has(> .glasshome-widget-controls) .glasshome-widget-art {\n bottom: var(--widget-grid-pad);\n height: min(\n calc(100% - 2 * var(--widget-grid-pad) - var(--widget-icon-box) - var(--widget-grid-gap)),\n 48cqi\n );\n }\n}\n@container widget (max-width: 179px) {\n .glasshome-widget-art {\n display: none;\n }\n}\n@container widget (max-height: 169px) {\n .glasshome-widget-head-aside {\n display: none;\n }\n}\n@container widget ((max-height: 129px) or (max-width: 139px)) {\n .glasshome-widget-head-text {\n min-height: 0;\n }\n .glasshome-widget-name {\n -webkit-line-clamp: 1;\n }\n .glasshome-widget-grid {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n gap: 2px;\n }\n .glasshome-widget-head-icon,\n .glasshome-widget-art,\n .glasshome-widget-eyebrow,\n .glasshome-widget-sub {\n display: none;\n }\n .glasshome-widget-glyph {\n display: block;\n }\n .glasshome-widget-reading-value {\n font-size: clamp(18px, min(34cqb, 20cqi), 30px);\n }\n .glasshome-widget-name {\n font-size: clamp(12px, min(18cqb, 11cqi), 15px);\n font-weight: 550;\n color: var(--muted-foreground);\n }\n}\n@container widget (max-height: 129px) and (min-width: 260px) {\n .glasshome-widget-grid {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n gap: var(--widget-grid-gap);\n }\n .glasshome-widget-name {\n font-size: clamp(14px, 22cqb, 18px);\n font-weight: 650;\n color: var(--foreground);\n }\n .glasshome-widget-eyebrow {\n display: block;\n }\n}\n\n.glasshome-widget-backdrop {\n position: absolute;\n inset: 0;\n z-index: -2;\n overflow: hidden;\n}\n.glasshome-widget-backdrop > img.area-night {\n opacity: 0;\n transition: opacity 700ms ease;\n}\n.glasshome-widget-backdrop > img.area-night[data-visible] {\n opacity: 1;\n}\n.glasshome-widget-backdrop > .glasshome-widget-backdrop-light {\n position: absolute;\n inset: 0;\n background: radial-gradient(90% 80% at 25% 30%, oklch(0.8 0.14 70), transparent 70%);\n mix-blend-mode: soft-light;\n opacity: var(--backdrop-light, 0);\n transition: opacity 500ms ease;\n}\n.glasshome-widget-backdrop::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background: linear-gradient(\n to bottom,\n color-mix(in oklch, var(--card) 82%, transparent) 0%,\n color-mix(in oklch, var(--card) 40%, transparent) 22%,\n transparent 42%,\n transparent 62%,\n color-mix(in oklch, var(--card) 45%, transparent) 82%,\n color-mix(in oklch, var(--card) 80%, transparent) 100%\n );\n}\n\n@container widget (max-width: 239px) {\n .glasshome-widget-choice [data-optional] {\n display: none;\n }\n}\n@container widget (max-width: 259px) {\n .glasshome-widget-head-aside {\n display: none;\n }\n}\n@container widget (max-width: 139px) {\n .glasshome-widget-controls {\n display: none;\n }\n}\n\n.glasshome-widget-controls {\n justify-content: flex-start;\n align-items: center;\n}\n.glasshome-widget-control.glasshome-widget-control {\n width: var(--widget-control-h);\n height: var(--widget-control-h);\n}\n.glasshome-widget-choice .glasshome-widget-control.glasshome-widget-control {\n width: calc(var(--widget-control-h) - 8px);\n height: calc(var(--widget-control-h) - 8px);\n}\n@container widget (max-width: 179px) and (min-height: 130px) {\n .glasshome-widget-grid:not(:has(> .glasshome-widget-backdrop)) .glasshome-widget-head-text {\n min-height: 0;\n }\n .glasshome-widget-grid:not(:has(> .glasshome-widget-backdrop)) .glasshome-widget-head {\n flex-direction: column;\n gap: 6px;\n }\n}\n.glasshome-widget-unit[data-degree] {\n vertical-align: top;\n margin-left: 0.02em;\n color: var(--foreground);\n}\n.glasshome-widget-control-wide.glasshome-widget-control-wide {\n height: var(--widget-control-h);\n gap: 6px;\n padding: 0 14px;\n}\n@container widget (max-width: 179px) {\n .glasshome-widget-grid:has(> .glasshome-widget-backdrop) .glasshome-widget-head-icon {\n display: none;\n }\n}\n.glasshome-widget-grid:has(> .glasshome-widget-backdrop)\n :is(\n .glasshome-widget-reading-value,\n .glasshome-widget-sub,\n .glasshome-widget-name,\n .glasshome-widget-eyebrow\n ) {\n text-shadow: 0 1px 8px color-mix(in oklch, var(--card) 75%, transparent);\n}\n.glasshome-widget-grid:has(> .glasshome-widget-backdrop)\n :is(.glasshome-widget-sub, .glasshome-widget-eyebrow) {\n color: color-mix(in oklch, var(--foreground) 82%, transparent);\n}\n/* Control glyphs and words keep their share of a control as it grows past 4x4. */\n.glasshome-widget-grid\n :is(.glasshome-widget-control, .glasshome-widget-control-wide)\n :is(iconify-icon, svg) {\n font-size: calc(var(--widget-control-h) * 0.43);\n width: 1em;\n height: 1em;\n}\n:is(.glasshome-widget-controls, .glasshome-widget-control-wide) {\n font-size: max(13px, calc(var(--widget-control-h) * 0.3));\n}\n/* A big tile with no art of its own carries its icon large and faint, so the glass is not an empty box. */\n@container widget (min-width: 300px) and (min-height: 260px) {\n .glasshome-widget-grid:not(\n :has(> .glasshome-widget-backdrop),\n :has(> .glasshome-widget-hero[data-art], > .glasshome-widget-art, > .glasshome-widget-layer)\n )\n > .glasshome-widget-glyph {\n display: block;\n right: -3%;\n bottom: -12%;\n font-size: min(78cqb, 52cqi);\n opacity: 0.1;\n }\n}\n/* A one-shot action confirms on its control and on the glyph, the one thing a compact tile shows. */\n.glasshome-widget-grid > .glasshome-widget-glyph {\n transition: opacity var(--duration-state) var(--ease-morph);\n}\n.glasshome-widget[data-confirmed] .glasshome-widget-glyph {\n opacity: 0.5;\n}\n.glasshome-widget-grid\n [data-confirmed]:is(.glasshome-widget-control, .glasshome-widget-control-wide) {\n --glass-base: color-mix(in srgb, var(--widget-color) 35%, transparent);\n transition: background-color var(--duration-state) var(--ease-morph);\n}\n\n/* === Sheet: what a held tile opens (framework/panel) ===\n * Rendered in a popover or dialog outside the widget's shadow root, so every rule\n * the sheet needs lives here, never in a widget's own utilities. */\n.glasshome-sheet {\n display: flex;\n flex-direction: column;\n gap: 18px;\n color: var(--foreground);\n}\n.glasshome-sheet [data-slot=\"swatch-picker\"] {\n max-width: 360px;\n}\n.glasshome-panel-section {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.glasshome-panel-label {\n margin: 0;\n font-size: 13px;\n font-weight: 500;\n color: var(--muted-foreground);\n}\n.glasshome-panel-rows {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 8px;\n}\n.glasshome-panel-row-wrap {\n position: relative;\n min-width: 0;\n}\n.glasshome-panel-row {\n --widget-wash: 22%;\n --widget-wash-2: 11%;\n --widget-radius: var(--radius-lg, 16px);\n --widget-icon-box: 34px;\n --widget-icon-glyph: 19px;\n position: relative;\n width: 100%;\n height: 56px;\n justify-content: flex-start;\n gap: 10px;\n padding: 0 12px 0 10px;\n overflow: hidden;\n text-align: left;\n touch-action: pan-y;\n}\n.glasshome-panel-row-static {\n cursor: default;\n scale: none;\n}\n.glasshome-panel-row-fill {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n.glasshome-panel-row-icon {\n position: relative;\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n}\n.glasshome-panel-row-icon-off {\n color: var(--muted-foreground);\n}\n.glasshome-panel-row-text {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n.glasshome-panel-row-name,\n.glasshome-panel-row-state,\n.glasshome-panel-fact-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n/* A reading may take a second line rather than lose its end (\"3 Moderate\"). */\n.glasshome-panel-fact-value {\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n}\n.glasshome-panel-row-name,\n.glasshome-panel-fact-value {\n font-size: 14px;\n font-weight: 500;\n color: var(--foreground);\n}\n.glasshome-panel-row-state,\n.glasshome-panel-fact-label {\n font-size: 12px;\n font-weight: 400;\n color: var(--muted-foreground);\n}\n.glasshome-panel-row-trailing {\n position: absolute;\n top: 50%;\n right: 10px;\n translate: 0 -50%;\n}\n.glasshome-panel-facts {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));\n row-gap: 10px;\n padding: 10px 4px 10px 0;\n overflow: hidden;\n border-radius: var(--radius-lg, 16px);\n --glass-base: color-mix(in srgb, var(--card) var(--material-clarity, 60%), transparent);\n backdrop-filter: blur(calc(var(--material-blur, 24px) * 0.6)) saturate(1.6);\n -webkit-backdrop-filter: blur(calc(var(--material-blur, 24px) * 0.6)) saturate(1.6);\n}\n/* Without blur a see-through strip is just see-through: it takes the card fill. */\n.reduce-blur .glasshome-panel-facts {\n --glass-base: var(--card);\n}\n.glasshome-panel-fact {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 8px;\n padding: 0 12px;\n box-shadow: -1px 0 0 color-mix(in oklch, var(--foreground) 10%, transparent);\n}\n.glasshome-panel-fact-icon {\n flex-shrink: 0;\n font-size: 18px;\n color: var(--muted-foreground);\n}\n\n/* Inset: the grid cell clips anything drawn outside the tile. */\n.glasshome-widget:focus-visible {\n outline: 2px solid var(--ring);\n outline-offset: -2px;\n}\n\n/* === Hold flood: the dock's hold fill (ui HOLD_MOTION), grown from the finger === */\n.glasshome-widget-hold-flood {\n position: absolute;\n translate: -50% -50%;\n border-radius: 9999px;\n background: color-mix(in oklch, var(--primary) 45%, transparent);\n pointer-events: none;\n scale: 0;\n opacity: 0;\n transition:\n scale var(--duration-state, 200ms) var(--ease-contract, ease-in),\n opacity var(--duration-state, 200ms) var(--ease-contract, ease-in);\n}\n.glasshome-widget-hold-flood[data-hold] {\n scale: 1;\n opacity: 1;\n transition-duration: var(--duration-hold, 250ms);\n transition-timing-function: linear;\n}\n.glasshome-widget-hold-flood[data-fired] {\n scale: 1;\n opacity: 0;\n}\n/* A row of ui buttons in a sheet (scenes, one-tap actions). */\n.glasshome-sheet-actions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n/* The sheet wears its tile: the tile's tone washed into the glass, its picture as a band behind\n the head that fades into the glass, so the tile reads as having grown open. */\n.glasshome-sheet-surface {\n --glass-wash: 20%;\n --glass-wash-2: 7%;\n --widget-icon-box: 48px;\n --widget-icon-glyph: 26px;\n}\n.glasshome-sheet-band {\n position: absolute;\n inset: 0 0 auto;\n height: 150px;\n overflow: hidden;\n pointer-events: none;\n mask-image: linear-gradient(180deg, #000 30%, transparent);\n}\n.glasshome-sheet-band > img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n opacity: 0.55;\n}\n.glasshome-sheet-surface > [data-slot$=\"-header\"],\n.glasshome-sheet-surface > [data-slot$=\"-body\"] {\n position: relative;\n}\n.glasshome-sheet-icon {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n", dr = !1, fr, pr = /* @__PURE__ */ new WeakSet();
700
+ function mr() {
701
+ return fr || (fr = new CSSStyleSheet(), fr.replaceSync(ur.replace(/:root\b/g, ":host").replace(/^\.dark\b/gm, ":host(.dark)"))), fr;
714
702
  }
715
- function dr(e) {
703
+ function hr(e) {
716
704
  if (typeof ShadowRoot < "u" && e instanceof ShadowRoot) {
717
- if (lr.has(e)) return;
718
- let t = ur();
719
- e.adoptedStyleSheets.includes(t) || (e.adoptedStyleSheets = [...e.adoptedStyleSheets, t]), lr.add(e);
705
+ if (pr.has(e)) return;
706
+ let t = mr();
707
+ e.adoptedStyleSheets.includes(t) || (e.adoptedStyleSheets = [...e.adoptedStyleSheets, t]), pr.add(e);
720
708
  return;
721
709
  }
722
- if (sr) return;
710
+ if (dr) return;
723
711
  let t = e ?? (typeof document > "u" ? void 0 : document);
724
712
  if (!t) return;
725
713
  if (t.head.querySelector?.("style[data-glasshome-tokens]")) {
726
- sr = !0;
714
+ dr = !0;
727
715
  return;
728
716
  }
729
717
  let n = t.createElement("style");
730
- n.setAttribute("data-glasshome-tokens", ""), n.textContent = or, t.head.appendChild(n), sr = !0;
718
+ n.setAttribute("data-glasshome-tokens", ""), n.textContent = ur, t.head.appendChild(n), dr = !0;
731
719
  }
732
720
  //#endregion
733
721
  //#region src/framework/variants/built-in-variants.ts
734
- var fr = {
722
+ var gr = {
735
723
  "classic-glass": { cssVars: {
736
724
  "--widget-padding": "1.5rem",
737
725
  "--widget-backdrop": "blur(var(--glass-blur, var(--material-blur, 24px))) saturate(calc(1.8 * var(--_material-vibrancy, 1))) brightness(calc(1 + (var(--_material-vibrancy, 1) - 1) * 0.2))"
@@ -751,19 +739,19 @@ var fr = {
751
739
  "--widget-backdrop": "blur(16px) saturate(1.8)"
752
740
  } }
753
741
  };
754
- function pr(e) {
755
- return Object.hasOwn(fr, e) ? fr[e] : void 0;
742
+ function _r(e) {
743
+ return Object.hasOwn(gr, e) ? gr[e] : void 0;
756
744
  }
757
745
  //#endregion
758
746
  //#region src/framework/backgrounds/WidgetSliderFill.tsx
759
- var mr = /*#__PURE__*/ V("<div>"), hr = e(() => void 0, "sliderFill.color");
760
- function gr(e) {
761
- return e.color !== void 0 && hr(), (() => {
762
- var t = mr();
747
+ var vr = /*#__PURE__*/ V("<div>"), yr = e(() => void 0, "sliderFill.color");
748
+ function br(e) {
749
+ return e.color !== void 0 && yr(), (() => {
750
+ var t = vr();
763
751
  return F((n) => {
764
752
  var r = J("glasshome-widget-slider-fill pointer-events-none absolute inset-0", e.isDragging ? "duration-0" : "transition-all duration-300 ease-out", e.class), i = {
765
753
  "--widget-fill-value": e.value,
766
- "z-index": an.BACKGROUND
754
+ "z-index": ln.BACKGROUND
767
755
  };
768
756
  return r !== n.e && N(t, n.e = r), n.t = B(t, i, n.t), n;
769
757
  }, {
@@ -774,13 +762,13 @@ function gr(e) {
774
762
  }
775
763
  //#endregion
776
764
  //#region src/framework/components/WidgetContent.tsx
777
- var _r = /*#__PURE__*/ V("<div>"), vr = /\bglasshome-widget-(head|hero|controls|backdrop|glyph|layer)\b/;
778
- function yr(e) {
779
- let t = un(j(W));
765
+ var xr = /*#__PURE__*/ V("<div>"), Sr = /\bglasshome-widget-(head|hero|controls|backdrop|glyph|layer)\b/;
766
+ function Cr(e) {
767
+ let t = mn(j(W));
780
768
  D(() => t?.setAccent(e.accent)), A(() => t?.setAccent(void 0));
781
- let n = fe(() => e.children), r = O(() => n.toArray().some((e) => e instanceof Element && vr.test(e.className)));
769
+ let n = fe(() => e.children), r = O(() => n.toArray().some((e) => e instanceof Element && Sr.test(e.className)));
782
770
  return (() => {
783
- var t = _r();
771
+ var t = xr();
784
772
  return I(t, n), F((n) => {
785
773
  var i = J(r() ? "glasshome-widget-grid" : "glasshome-widget-content", e.class), a = e.accent ? { "--widget-color": e.accent } : void 0;
786
774
  return i !== n.e && N(t, n.e = i), n.t = B(t, a, n.t), n;
@@ -792,15 +780,15 @@ function yr(e) {
792
780
  }
793
781
  //#endregion
794
782
  //#region src/framework/components/WidgetStatus.tsx
795
- var br = /*#__PURE__*/ V("<p>");
796
- function xr(e) {
783
+ var wr = /*#__PURE__*/ V("<p>");
784
+ function Tr(e) {
797
785
  return (() => {
798
- var t = br();
786
+ var t = wr();
799
787
  return I(t, (() => {
800
788
  var t = L(() => !!e.isUnavailable);
801
789
  return () => t() ? "Unavailable" : e.children;
802
790
  })()), F((n) => {
803
- var r = J("glasshome-widget-status", "relative", e.dimmed && "opacity-40", e.class), i = an.ACTIONS;
791
+ var r = J("glasshome-widget-status", "relative", e.dimmed && "opacity-40", e.class), i = ln.ACTIONS;
804
792
  return r !== n.e && N(t, n.e = r), i !== n.t && z(t, "z-index", n.t = i), n;
805
793
  }, {
806
794
  e: void 0,
@@ -810,20 +798,20 @@ function xr(e) {
810
798
  }
811
799
  //#endregion
812
800
  //#region src/framework/components/WidgetTitle.tsx
813
- var Sr = /*#__PURE__*/ V("<span class=\"glasshome-widget-badge shrink-0\">"), Cr = /*#__PURE__*/ V("<div><h3 class=glasshome-widget-title>");
814
- function wr(e) {
801
+ var Er = /*#__PURE__*/ V("<span class=\"glasshome-widget-badge shrink-0\">"), Dr = /*#__PURE__*/ V("<div><h3 class=glasshome-widget-title>");
802
+ function Or(e) {
815
803
  return (() => {
816
- var t = Cr(), n = t.firstChild;
804
+ var t = Dr(), n = t.firstChild;
817
805
  return I(n, () => e.children), I(t, P(E, {
818
806
  get when() {
819
807
  return L(() => e.badge !== void 0)() && e.badge > 0;
820
808
  },
821
809
  get children() {
822
- var t = Sr();
810
+ var t = Er();
823
811
  return I(t, () => e.badge), t;
824
812
  }
825
813
  }), null), F((n) => {
826
- var r = J("relative flex items-center gap-2", e.class), i = an.ACTIONS;
814
+ var r = J("relative flex items-center gap-2", e.class), i = ln.ACTIONS;
827
815
  return r !== n.e && N(t, n.e = r), i !== n.t && z(t, "z-index", n.t = i), n;
828
816
  }, {
829
817
  e: void 0,
@@ -832,39 +820,6 @@ function wr(e) {
832
820
  })();
833
821
  }
834
822
  //#endregion
835
- //#region src/framework/utils/clipboard.ts
836
- async function Tr(e) {
837
- if (navigator.clipboard?.writeText) try {
838
- return await navigator.clipboard.writeText(e), !0;
839
- } catch {}
840
- return Er(e);
841
- }
842
- function Er(e) {
843
- let t = Dr(), n = document.createElement("textarea");
844
- n.value = e, n.setAttribute("readonly", ""), n.style.position = "fixed", n.style.top = "0", n.style.left = "0", n.style.opacity = "0", (t?.parentElement ?? document.body).append(n);
845
- try {
846
- return n.focus(), n.select(), n.setSelectionRange(0, e.length), n.getRootNode().activeElement === n && document.execCommand("copy");
847
- } catch {
848
- return !1;
849
- } finally {
850
- n.remove(), t?.focus();
851
- }
852
- }
853
- function Dr() {
854
- let e = document.activeElement;
855
- for (; e?.shadowRoot?.activeElement;) e = e.shadowRoot.activeElement;
856
- return e instanceof HTMLElement ? e : null;
857
- }
858
- function Or(e = 2e3) {
859
- let [t, n] = k("idle"), r;
860
- return A(() => clearTimeout(r)), {
861
- state: t,
862
- copy: async (t) => {
863
- n(await Tr(t) ? "copied" : "failed"), clearTimeout(r), r = setTimeout(() => n("idle"), e);
864
- }
865
- };
866
- }
867
- //#endregion
868
823
  //#region src/framework/utils/entity-aggregation.ts
869
824
  function kr(e, t = !1) {
870
825
  let n = e[0];
@@ -1117,9 +1072,9 @@ function Br(e) {
1117
1072
  //#region src/framework/core/Widget.tsx
1118
1073
  var Vr = /*#__PURE__*/ V("<span class=glasshome-widget-hold-flood aria-hidden=true>"), Hr = /*#__PURE__*/ V("<div class=\"glasshome-widget-frame relative h-full w-full\"><div><div class=\"relative h-full w-full\"></div></div><div class=\"glasshome-widget-halo glass-halo rounded-xl\"aria-hidden=true>"), Ur = /*#__PURE__*/ V("<div class=\"glasshome-widget-loading pointer-events-none absolute inset-0 animate-pulse\">"), Wr = /*#__PURE__*/ V("<div class=\"flex h-full w-full flex-col items-center justify-center gap-2 text-center\">"), Gr = /*#__PURE__*/ V("<div class=\"text-muted-foreground flex items-center justify-center\">"), Kr = /*#__PURE__*/ V("<h3 class=\"text-foreground text-sm font-semibold\">"), qr = /*#__PURE__*/ V("<p class=\"text-muted-foreground text-xs\">"), Jr = 2e3;
1119
1074
  function Yr(t) {
1120
- let n = j(W), r = On(() => ({ hold: { action: () => (G.get(n ?? {}) ?? G.get(f))?.("edit") } }));
1075
+ let n = j(W), r = Mn(() => ({ hold: { action: () => (G.get(n ?? {}) ?? G.get(f))?.("edit") } }));
1121
1076
  A(r.dispose);
1122
- let i = un(n), a = !!n && !(cn in n), o = On(() => ({ hold: i?.hasSheet() ? { action: () => (G.get(n ?? {}) ?? G.get(f))?.() } : void 0 }));
1077
+ let i = mn(n), a = !!n && !(fn in n), o = Mn(() => ({ hold: i?.hasSheet() ? { action: () => (G.get(n ?? {}) ?? G.get(f))?.() } : void 0 }));
1123
1078
  A(o.dispose);
1124
1079
  let s = () => t.emptyState && n ? r : t.gestures ?? (a ? o : void 0);
1125
1080
  a && (D(() => n?.onHoldable?.(!t.emptyState && !!s()?.holds?.())), A(() => n?.onHoldable?.(!1))), D(() => {
@@ -1148,16 +1103,16 @@ function Yr(t) {
1148
1103
  t.observe(e), A(() => t.disconnect());
1149
1104
  }), he(() => {
1150
1105
  let e = c()?.getRootNode();
1151
- dr(typeof ShadowRoot < "u" && e instanceof ShadowRoot || typeof Document < "u" && e instanceof Document ? e : void 0);
1106
+ hr(typeof ShadowRoot < "u" && e instanceof ShadowRoot || typeof Document < "u" && e instanceof Document ? e : void 0);
1152
1107
  });
1153
1108
  let f = {
1154
1109
  ...n,
1155
1110
  updateConfig: n?.updateConfig ?? (() => {}),
1156
1111
  dimensions: e(() => u(), "ctx.dimensions")
1157
1112
  };
1158
- n && Object.defineProperty(f, cn, { value: n });
1113
+ n && Object.defineProperty(f, fn, { value: n });
1159
1114
  let p = O(() => {
1160
- if (t.variant) return typeof t.variant == "string" ? pr(t.variant) : t.variant.styles;
1115
+ if (t.variant) return typeof t.variant == "string" ? _r(t.variant) : t.variant.styles;
1161
1116
  }), m = e(() => t.gradient, "widget.gradient"), h = () => !!t.tone && t.tone !== "neutral" || !!t.color, g = O(() => ({
1162
1117
  ...p()?.cssVars || {},
1163
1118
  ...t.tone ? { "--widget-color": `var(--tone-${t.tone})` } : {},
@@ -1197,15 +1152,15 @@ function Yr(t) {
1197
1152
  top: `${w.y}px`,
1198
1153
  width: `${w.r * 2}px`,
1199
1154
  height: `${w.r * 2}px`,
1200
- "z-index": an.BACKGROUND
1155
+ "z-index": ln.BACKGROUND
1201
1156
  });
1202
1157
  return P(W.Provider, {
1203
1158
  value: f,
1204
1159
  get children() {
1205
- return P(Jn.Provider, {
1160
+ return P(Qn.Provider, {
1206
1161
  value: () => t.confirmed === !0,
1207
1162
  get children() {
1208
- return P(kn.Provider, {
1163
+ return P(Nn.Provider, {
1209
1164
  value: u,
1210
1165
  get children() {
1211
1166
  return [(() => {
@@ -1246,10 +1201,10 @@ function Yr(t) {
1246
1201
  var e = L(() => !!t.loading);
1247
1202
  return () => e() && (() => {
1248
1203
  var e = Ur();
1249
- return F((t) => z(e, "z-index", an.OVERLAY)), e;
1204
+ return F((t) => z(e, "z-index", ln.OVERLAY)), e;
1250
1205
  })();
1251
1206
  })(), null), F((e) => {
1252
- var r = J("glasshome-widget glass", "relative h-full w-full overflow-hidden rounded-xl select-none", p()?.class, t.class), o = _(), s = h() ? "" : void 0, c = t.confirmed || void 0, l = v() ? 0 : void 0, u = an.CONTENT, d = g(), f = h() ? "" : void 0;
1207
+ var r = J("glasshome-widget glass", "relative h-full w-full overflow-hidden rounded-xl select-none", p()?.class, t.class), o = _(), s = h() ? "" : void 0, c = t.confirmed || void 0, l = v() ? 0 : void 0, u = ln.CONTENT, d = g(), f = h() ? "" : void 0;
1253
1208
  return r !== e.e && N(n, e.e = r), e.t = B(n, o, e.t), s !== e.a && R(n, "data-toned", e.a = s), c !== e.o && R(n, "data-confirmed", e.o = c), l !== e.i && R(n, "tabindex", e.i = l), u !== e.n && z(i, "z-index", e.n = u), e.s = B(a, d, e.s), f !== e.h && R(a, "data-toned", e.h = f), e;
1254
1209
  }, {
1255
1210
  e: void 0,
@@ -1315,7 +1270,7 @@ function Xr(e) {
1315
1270
  })();
1316
1271
  }
1317
1272
  var Y = Yr;
1318
- Y.Content = yr, Y.Icon = In, Y.Title = wr, Y.Status = xr, Y.Value = Br, Y.SliderFill = gr, Y.Head = Xn, Y.Hero = Zn, Y.Controls = Qn, Y.Stepper = $n, Y.Choice = er, Y.Action = tr, Y.Chip = nr, Y.Backdrop = ir, Y.Layer = rr, Y.Glyph = ar, _e(["keydown"]);
1273
+ Y.Content = Cr, Y.Icon = Bn, Y.Title = Or, Y.Status = Tr, Y.Value = Br, Y.SliderFill = br, Y.Head = er, Y.Hero = tr, Y.Controls = nr, Y.Stepper = rr, Y.Choice = ir, Y.Action = ar, Y.Chip = or, Y.Backdrop = cr, Y.Layer = sr, Y.Glyph = lr, _e(["keydown"]);
1319
1274
  //#endregion
1320
1275
  //#region src/framework/panel/panel.tsx
1321
1276
  var Zr = /*#__PURE__*/ V("<section class=glasshome-panel-section><h3 class=glasshome-panel-label>"), Qr = /*#__PURE__*/ V("<div class=glasshome-panel-rows>"), $r = /*#__PURE__*/ V("<span class=\"glasshome-widget-slider-fill glasshome-panel-row-fill\">"), ei = /*#__PURE__*/ V("<span class=\"glasshome-widget-icon glass glasshome-panel-row-icon\">"), ti = /*#__PURE__*/ V("<span class=glasshome-panel-row-state>"), ni = /*#__PURE__*/ V("<span class=glasshome-panel-row-text><span class=glasshome-panel-row-name>"), ri = /*#__PURE__*/ V("<span class=glasshome-panel-row-trailing>"), ii = /*#__PURE__*/ V("<div class=glasshome-panel-row-wrap>"), ai = /*#__PURE__*/ V("<div>"), oi = /*#__PURE__*/ V("<div class=\"glasshome-panel-facts glass\">"), si = /*#__PURE__*/ V("<div class=glasshome-panel-fact><span class=glasshome-panel-row-text><span class=glasshome-panel-fact-label></span><span class=glasshome-panel-fact-value>"), ci = 8, li = (e, t, n) => Math.min(n, Math.max(t, e));
@@ -1331,13 +1286,13 @@ function ui(e) {
1331
1286
  return A(() => clearTimeout(a)), {
1332
1287
  onPointerDown: (o) => {
1333
1288
  if (o.button !== 0 || n) return;
1334
- let s = o.target instanceof Element ? o.target.closest(Dn) : null;
1289
+ let s = o.target instanceof Element ? o.target.closest(jn) : null;
1335
1290
  s && s !== o.currentTarget || (n = {
1336
1291
  x: o.clientX,
1337
1292
  y: o.clientY,
1338
1293
  id: o.pointerId
1339
1294
  }, o.currentTarget.setPointerCapture?.(o.pointerId), r = !1, i = !1, e.onHold && (a = setTimeout(() => {
1340
- i = !0, e.onHold?.(), t?.onHeld?.();
1295
+ i = !0, qt(), e.onHold?.(), t?.onHeld?.();
1341
1296
  }, qe)));
1342
1297
  },
1343
1298
  onPointerMove: (t) => {
@@ -1674,7 +1629,7 @@ function Ci(e) {
1674
1629
  return !!_i[e]?.tap || !!_i[e]?.setLevel;
1675
1630
  }
1676
1631
  function wi(e) {
1677
- let t = C(() => e.entityId), { callService: n } = en(), [r, i] = k();
1632
+ let t = C(() => e.entityId), { callService: n } = an(), [r, i] = k();
1678
1633
  return D(() => {
1679
1634
  t(), i(void 0);
1680
1635
  }), P(E, {
@@ -1749,7 +1704,7 @@ var ji = (e) => JSON.stringify(e, null, 2), Mi = {
1749
1704
  failed: "text-destructive"
1750
1705
  };
1751
1706
  function Pi(e) {
1752
- let { state: t, copy: n } = Or();
1707
+ let { state: t, copy: n } = Yt();
1753
1708
  return P(Te, {
1754
1709
  variant: "ghost",
1755
1710
  size: "icon",
@@ -2105,7 +2060,7 @@ function Yi(e, t) {
2105
2060
  }
2106
2061
  //#endregion
2107
2062
  //#region src/framework/dialogs/WidgetDialog.tsx
2108
- var Xi = /*#__PURE__*/ V("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"></path><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\">"), Zi = /*#__PURE__*/ V("<div class=\"bg-muted/30 rounded-lg p-2 text-center md:p-6\"><p class=\"text-muted-foreground text-sm\">No edit options available"), Qi = /*#__PURE__*/ V("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><line x1=4 y1=21 x2=4 y2=14></line><line x1=4 y1=10 x2=4 y2=3></line><line x1=12 y1=21 x2=12 y2=12></line><line x1=12 y1=8 x2=12 y2=3></line><line x1=20 y1=21 x2=20 y2=16></line><line x1=20 y1=12 x2=20 y2=3></line><line x1=1 y1=14 x2=7 y2=14></line><line x1=9 y1=8 x2=15 y2=8></line><line x1=17 y1=16 x2=23 y2=16>"), $i = /*#__PURE__*/ V("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><path d=\"m8 2 1.88 1.88\"></path><path d=\"M14.12 3.88 16 2\"></path><path d=\"M9 7.13v-1a3.003 3.003 0 1 1 6 0v1\"></path><path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6\"></path><path d=\"M12 20v-9\"></path><path d=\"M6.53 9C4.6 8.8 3 7.1 3 5\"></path><path d=\"M6 13H2\"></path><path d=\"M3 21c0-2.1 1.7-3.9 3.8-4\"></path><path d=\"M20.97 5c0 2.1-1.6 3.8-3.5 4\"></path><path d=\"M22 13h-4\"></path><path d=\"M17.2 17c2.1.1 3.8 1.9 3.8 4\">"), ea = /*#__PURE__*/ V("<div class=glasshome-sheet>"), ta = /*#__PURE__*/ V("<div class=glasshome-sheet-band aria-hidden=true><img alt>"), na = /*#__PURE__*/ V("<span class=\"glasshome-widget-icon glass glass-tint glasshome-sheet-icon\">"), ra = /*#__PURE__*/ V("<span class=\"inline-flex size-3.5 shrink-0 items-center\">"), ia = (e) => Jt(e), aa = {
2063
+ var Xi = /*#__PURE__*/ V("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"></path><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\">"), Zi = /*#__PURE__*/ V("<div class=\"bg-muted/30 rounded-lg p-2 text-center md:p-6\"><p class=\"text-muted-foreground text-sm\">No edit options available"), Qi = /*#__PURE__*/ V("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><line x1=4 y1=21 x2=4 y2=14></line><line x1=4 y1=10 x2=4 y2=3></line><line x1=12 y1=21 x2=12 y2=12></line><line x1=12 y1=8 x2=12 y2=3></line><line x1=20 y1=21 x2=20 y2=16></line><line x1=20 y1=12 x2=20 y2=3></line><line x1=1 y1=14 x2=7 y2=14></line><line x1=9 y1=8 x2=15 y2=8></line><line x1=17 y1=16 x2=23 y2=16>"), $i = /*#__PURE__*/ V("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><path d=\"m8 2 1.88 1.88\"></path><path d=\"M14.12 3.88 16 2\"></path><path d=\"M9 7.13v-1a3.003 3.003 0 1 1 6 0v1\"></path><path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6\"></path><path d=\"M12 20v-9\"></path><path d=\"M6.53 9C4.6 8.8 3 7.1 3 5\"></path><path d=\"M6 13H2\"></path><path d=\"M3 21c0-2.1 1.7-3.9 3.8-4\"></path><path d=\"M20.97 5c0 2.1-1.6 3.8-3.5 4\"></path><path d=\"M22 13h-4\"></path><path d=\"M17.2 17c2.1.1 3.8 1.9 3.8 4\">"), ea = /*#__PURE__*/ V("<div class=glasshome-sheet>"), ta = /*#__PURE__*/ V("<div class=glasshome-sheet-band aria-hidden=true><img alt>"), na = /*#__PURE__*/ V("<span class=\"glasshome-widget-icon glass glass-tint glasshome-sheet-icon\">"), ra = /*#__PURE__*/ V("<span class=\"inline-flex size-3.5 shrink-0 items-center\">"), ia = (e) => Qt(e), aa = {
2109
2064
  sm: "sm",
2110
2065
  md: "md",
2111
2066
  lg: "lg",
@@ -2181,13 +2136,13 @@ function sa(e) {
2181
2136
  return t.debugData;
2182
2137
  } })
2183
2138
  }), e;
2184
- }, v = j(W), y = un(v);
2139
+ }, v = j(W), y = mn(v);
2185
2140
  D(() => y?.setHasSheet(t.sheet !== void 0)), A(() => y?.setHasSheet(!1));
2186
2141
  let b = () => ({
2187
2142
  icon: t.tile?.icon ?? y?.icon(),
2188
2143
  tone: t.tile?.tone ?? y?.accent() ?? y?.tone(),
2189
2144
  backdrop: t.tile?.backdrop
2190
- }), x = () => v?.developer?.() ?? !1, S = () => H() === "controls" && t.sheet !== void 0, ee = ca(), C = () => v?.anchor?.(), w = () => S() && !ee() && C() !== void 0, te = Or(), ne = () => {
2145
+ }), x = () => v?.developer?.() ?? !1, S = () => H() === "controls" && t.sheet !== void 0, ee = ca(), C = () => v?.anchor?.(), w = () => S() && !ee() && C() !== void 0, te = Yt(), ne = () => {
2191
2146
  if (t.debugData === void 0) return;
2192
2147
  let e = typeof t.debugData == "string" ? t.debugData : JSON.stringify(t.debugData, null, 2);
2193
2148
  te.copy(e);
@@ -3042,7 +2997,7 @@ function lo(e) {
3042
2997
  }
3043
2998
  function uo(e, t) {
3044
2999
  let n = o.object(e);
3045
- return n.default(Yt(n)).meta({ title: t.title });
3000
+ return n.default($t(n)).meta({ title: t.title });
3046
3001
  }
3047
3002
  function fo(e) {
3048
3003
  return e.def;
@@ -3142,8 +3097,8 @@ function bo(e) {
3142
3097
  //#endregion
3143
3098
  //#region src/framework/image-src.ts
3144
3099
  function xo(e, t) {
3145
- let n = Bt(e);
3146
- return n === void 0 ? Ht(e) : t?.[n]?.src;
3100
+ let n = Vt(e);
3101
+ return n === void 0 ? Ut(e) : t?.[n]?.src;
3147
3102
  }
3148
3103
  //#endregion
3149
3104
  //#region src/shared/spline.ts
@@ -3181,7 +3136,7 @@ function Co() {
3181
3136
  //#region src/version.ts
3182
3137
  var wo = {
3183
3138
  name: "@glasshome/widget-sdk",
3184
- version: "1.22.0",
3139
+ version: "1.22.2",
3185
3140
  description: "SDK for building GlassHome dashboard widgets with SolidJS",
3186
3141
  keywords: [
3187
3142
  "dashboard",
@@ -3262,7 +3217,7 @@ var wo = {
3262
3217
  zod: "^4.1.13"
3263
3218
  },
3264
3219
  devDependencies: {
3265
- "@glasshome/ui": "1.26.0",
3220
+ "@glasshome/ui": "1.30.0",
3266
3221
  "@solidjs/testing-library": "^0.8.10",
3267
3222
  "@types/bun": "^1.4.0",
3268
3223
  "@types/node": "^25.2.2",
@@ -3277,10 +3232,10 @@ var wo = {
3277
3232
  },
3278
3233
  peerDependencies: {
3279
3234
  "@glasshome/sync-layer": "0.9.1",
3280
- "@glasshome/ui": "1.26.0",
3235
+ "@glasshome/ui": "1.30.0",
3281
3236
  "solid-js": "^1.9.11"
3282
3237
  },
3283
3238
  engines: { node: ">=18" }
3284
3239
  }.version;
3285
3240
  //#endregion
3286
- export { Se as Badge, we as Button, Ee as ButtonGroup, Oe as Carousel, ke as CarouselContent, Ae as CarouselDots, je as CarouselItem, Me as CarouselNext, Ne as CarouselPrevious, Pe as ColorDisc, Fe as ColorSlider, Ie as ColorWheel, Le as CountPill, Je as Icon, Ye as Input, Xe as Label, wi as PanelEntityRow, mi as PanelFacts, pi as PanelRow, fi as PanelRows, di as PanelSection, $e as Progress, et as ResponsiveDialog, tt as ResponsiveDialogBody, rt as ResponsiveDialogClose, it as ResponsiveDialogContent, at as ResponsiveDialogDescription, ot as ResponsiveDialogFooter, ct as ResponsiveDialogHeader, lt as ResponsiveDialogTitle, wo as SDK_VERSION, ut as SchemaForm, dt as SectionIcon, ht as SectionTitle, gt as Select, _t as SelectContent, vt as SelectItem, yt as SelectTrigger, bt as SelectValue, xt as Slider, St as SwatchPicker, Ct as Switch, wt as Tabs, Et as TabsContent, Ot as TabsList, At as TabsTrigger, Mt as TemperatureBar, Nt as Toggle, Pt as ToggleGroup, It as ToggleGroupItem, Ya as ToneSchema, Y as Widget, tr as WidgetAction, ir as WidgetBackdrop, nr as WidgetChip, er as WidgetChoice, yr as WidgetContent, Qn as WidgetControls, W as WidgetCtx, qi as WidgetDebugTab, Gi as WidgetDebugView, sa as WidgetDialog, ar as WidgetGlyph, Xn as WidgetHead, Zn as WidgetHero, In as WidgetIcon, rr as WidgetLayer, r as WidgetManifestSchema, kn as WidgetSizeCtx, gr as WidgetSliderFill, xr as WidgetStatus, $n as WidgetStepper, wr as WidgetTitle, Br as WidgetValue, Ai as buildDebugData, g as byDomain, kr as calculateLightGroup, Ar as calculateSensorGroup, Tr as copyText, Fr as countActiveEntities, bo as defineConfig, Xt as defineWidget, t as deprecations, yo as field, n as formatDeprecation, i as formatSchemaError, Pr as getEntityAttribute, s as getForecasts, c as getStream, l as getWebRtcClientConfig, u as hassMediaUrl, zt as imagePreset, xo as imageSrc, Vt as imageUrl, dr as injectTokens, Co as isDark, Nr as isEntityActive, Ci as isPanelControllable, Ut as mediaUrl, So as monotoneCubicPath, Wt as parseColor, Gt as presetValue, d as sendWebRtcCandidate, f as startWebRtcSession, p as state, Ja as svgColors, m as trackEntityHistory, h as untrackEntityHistory, _ as useArea, v as useCalendarEvents, y as useCamera, Mn as useConfirm, b as useConnection, Or as useCopyText, x as useCurrency, Ua as useDaylight, S as useEntities, ee as useEntity, w as useEntityHistory, te as useEntityStatistics, ne as useForecast, re as useHassConfig, ja as useIntersectionPause, ie as useLocale, Aa as useMaterial, Wa as useReducedMotion, en as useService, oe as useStore, se as useTemperatureUnit, rn as useToggle, nn as useTurnOff, tn as useTurnOn, de as useUnitSystem, Zt as useWidgetContext, ua as useWidgetDashboard, on as useWidgetDialog, An as useWidgetDimensions, Ga as useWidgetEntityGroup, On as useWidgetGestures, fa as useWidgetViewer, Xa as widgetFields, a as z };
3241
+ export { Se as Badge, we as Button, Ee as ButtonGroup, Oe as Carousel, ke as CarouselContent, Ae as CarouselDots, je as CarouselItem, Me as CarouselNext, Ne as CarouselPrevious, Pe as ColorDisc, Fe as ColorSlider, Ie as ColorWheel, Le as CountPill, Je as Icon, Ye as Input, Xe as Label, wi as PanelEntityRow, mi as PanelFacts, pi as PanelRow, fi as PanelRows, di as PanelSection, $e as Progress, et as ResponsiveDialog, tt as ResponsiveDialogBody, rt as ResponsiveDialogClose, it as ResponsiveDialogContent, at as ResponsiveDialogDescription, ot as ResponsiveDialogFooter, ct as ResponsiveDialogHeader, lt as ResponsiveDialogTitle, wo as SDK_VERSION, ut as SchemaForm, dt as SectionIcon, ht as SectionTitle, gt as Select, _t as SelectContent, vt as SelectItem, yt as SelectTrigger, bt as SelectValue, xt as Slider, St as SwatchPicker, Ct as Switch, wt as Tabs, Et as TabsContent, Ot as TabsList, At as TabsTrigger, Mt as TemperatureBar, Nt as Toggle, Pt as ToggleGroup, It as ToggleGroupItem, Ya as ToneSchema, Y as Widget, ar as WidgetAction, cr as WidgetBackdrop, or as WidgetChip, ir as WidgetChoice, Cr as WidgetContent, nr as WidgetControls, W as WidgetCtx, qi as WidgetDebugTab, Gi as WidgetDebugView, sa as WidgetDialog, lr as WidgetGlyph, er as WidgetHead, tr as WidgetHero, Bn as WidgetIcon, sr as WidgetLayer, r as WidgetManifestSchema, Nn as WidgetSizeCtx, br as WidgetSliderFill, Tr as WidgetStatus, rr as WidgetStepper, Or as WidgetTitle, Br as WidgetValue, Ai as buildDebugData, g as byDomain, kr as calculateLightGroup, Ar as calculateSensorGroup, zt as copyText, Fr as countActiveEntities, bo as defineConfig, en as defineWidget, t as deprecations, yo as field, n as formatDeprecation, i as formatSchemaError, Pr as getEntityAttribute, s as getForecasts, c as getStream, l as getWebRtcClientConfig, u as hassMediaUrl, Bt as imagePreset, xo as imageSrc, Ht as imageUrl, hr as injectTokens, Co as isDark, Nr as isEntityActive, Ci as isPanelControllable, Wt as mediaUrl, So as monotoneCubicPath, Gt as parseColor, Kt as presetValue, d as sendWebRtcCandidate, f as startWebRtcSession, p as state, Ja as svgColors, m as trackEntityHistory, h as untrackEntityHistory, _ as useArea, v as useCalendarEvents, y as useCamera, In as useConfirm, b as useConnection, Jt as useCopyText, x as useCurrency, Ua as useDaylight, S as useEntities, ee as useEntity, w as useEntityHistory, te as useEntityStatistics, ne as useForecast, re as useHassConfig, ja as useIntersectionPause, ie as useLocale, Aa as useMaterial, Wa as useReducedMotion, an as useService, oe as useStore, se as useTemperatureUnit, cn as useToggle, sn as useTurnOff, on as useTurnOn, de as useUnitSystem, tn as useWidgetContext, ua as useWidgetDashboard, un as useWidgetDialog, Pn as useWidgetDimensions, Ga as useWidgetEntityGroup, Mn as useWidgetGestures, fa as useWidgetViewer, Xa as widgetFields, a as z };
package/dist/schemas.js CHANGED
@@ -1,2 +1 @@
1
- import { GridSizeSchema as e, PublishBodySchema as t, PublishConfirmSchema as n, PublishRequestSchema as r, capabilitiesSchema as i, capabilityGrantSchema as a, formatSchemaError as o, parseGridSize as s, publishManifestSchema as c, serializeGridSize as l, widgetManifestSchema as u, widgetManifestSchema as d } from "@glasshome/widget-contract";
2
- export { e as GridSizeSchema, t as PublishBodySchema, n as PublishConfirmSchema, r as PublishRequestSchema, d as WidgetManifestSchema, i as capabilitiesSchema, a as capabilityGrantSchema, o as formatSchemaError, s as parseGridSize, c as publishManifestSchema, l as serializeGridSize, u as widgetManifestSchema };
1
+ export { GridSizeSchema, PublishBodySchema, PublishConfirmSchema, PublishRequestSchema, widgetManifestSchema as WidgetManifestSchema, capabilitiesSchema, capabilityGrantSchema, formatSchemaError, parseGridSize, publishManifestSchema, serializeGridSize, widgetManifestSchema } from "@glasshome/widget-contract";
@@ -253,15 +253,10 @@ var ue = /import\s*(\{[^}]*\}|\*\s*as\s+[\w$]+)\s*from\s*["']@glasshome\/widget-
253
253
  function k(e) {
254
254
  let t = /* @__PURE__ */ new Set();
255
255
  de.test(e) && t.add("*");
256
- for (let [, n = ""] of e.matchAll(ue)) {
257
- if (!n.startsWith("{")) {
258
- t.add("*");
259
- continue;
260
- }
261
- for (let e of n.slice(1, -1).split(",")) {
262
- let n = e.trim().split(/\s+as\s+/)[0];
263
- n && t.add(n);
264
- }
256
+ for (let [, n = ""] of e.matchAll(ue)) if (!n.startsWith("{")) t.add("*");
257
+ else for (let e of n.slice(1, -1).split(",")) {
258
+ let n = e.trim().split(/\s+as\s+/)[0];
259
+ n && t.add(n);
265
260
  }
266
261
  return t;
267
262
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glasshome/widget-sdk",
3
- "version": "1.22.0",
3
+ "version": "1.22.2",
4
4
  "description": "SDK for building GlassHome dashboard widgets with SolidJS",
5
5
  "keywords": [
6
6
  "dashboard",
@@ -85,7 +85,7 @@
85
85
  "zod": "^4.1.13"
86
86
  },
87
87
  "devDependencies": {
88
- "@glasshome/ui": "1.26.0",
88
+ "@glasshome/ui": "1.30.0",
89
89
  "@solidjs/testing-library": "^0.8.10",
90
90
  "@types/bun": "^1.4.0",
91
91
  "@types/node": "^25.2.2",
@@ -100,7 +100,7 @@
100
100
  },
101
101
  "peerDependencies": {
102
102
  "@glasshome/sync-layer": "0.9.1",
103
- "@glasshome/ui": "1.26.0",
103
+ "@glasshome/ui": "1.30.0",
104
104
  "solid-js": "^1.9.11"
105
105
  },
106
106
  "engines": {
@@ -1,9 +0,0 @@
1
- export type CopyState = "idle" | "copied" | "failed";
2
- /** Dashboards are reached over plain http on the LAN, where navigator.clipboard
3
- * does not exist; the selection path is the only copy those installs have. */
4
- export declare function copyText(text: string): Promise<boolean>;
5
- /** Copy plus the state a control needs to say what happened. */
6
- export declare function useCopyText(resetAfterMs?: number): {
7
- state: import("solid-js").Accessor<CopyState>;
8
- copy: (text: string) => Promise<void>;
9
- };