@boost33/ui 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,23 +49,22 @@ package** — until then it has one consumer, which is a fork with a version num
49
49
 
50
50
  `LaunchLoader` is presentational. The page that renders it owns the timing and
51
51
  passes in a `caption` and a `progress` (0–100, or `null` while there is no
52
- honest number). The four gradient stops are props too, darkest first. The
53
- package holds no product's colours.
54
- **`stops[0]` and `stops[1]` must each be at or under relative luminance
55
- 0.183**: the caption sits straight on the mesh, and its dark centre is built
56
- from those two. `npm run launch-contrast-check`
57
- measures it.
52
+ honest number). The background is built in and the same for every product:
53
+ black, with one blurred brand-orange glow rising from below the middle of the
54
+ screen. There are no product colours to pass; `stops` is deprecated and ignored
55
+ since 0.5.1. The caption sits straight on the glow, and
56
+ `npm run launch-contrast-check` measures it.
58
57
 
59
- The mesh is markup with inline styles, so it paints in the same HTML chunk as
60
- the component on both sides of a hop. Inline the ground colour too, so the
61
- instant before the markup parses is already the screen's base tone:
58
+ The glow is drawn by the package stylesheet and takes no prop, so both sides of
59
+ a hop paint the identical screen. Inline the ground colour too, so the instant
60
+ before the stylesheet and the markup arrive is already black rather than white:
62
61
 
63
62
  ```tsx
64
63
  import { LaunchLoader, launchBackdropCss } from '@boost33/ui'
65
64
 
66
- <style dangerouslySetInnerHTML={{ __html: launchBackdropCss(stops) }} />
67
- <LaunchLoader stops={stops} caption={caption} progress={progress} />
65
+ <style dangerouslySetInnerHTML={{ __html: launchBackdropCss() }} />
66
+ <LaunchLoader caption={caption} progress={progress} />
68
67
  ```
69
68
 
70
69
  An animated backdrop, when one exists, goes in the `backdrop` slot. The screen
71
- must stay complete without it. See `CHANGELOG.md` (B33-1389) for the full contract.
70
+ must stay complete without it. See `CHANGELOG.md` (B33-1389, B33-1401) for the full contract.
@@ -12,8 +12,12 @@ export interface LaunchLoaderProps {
12
12
  * package's -- the same reason WalletChip's labels take whole templates.
13
13
  */
14
14
  caption: string;
15
- /** The destination's four gradient stops, darkest first. See LaunchGradientStops. */
16
- stops: LaunchGradientStops;
15
+ /**
16
+ * @deprecated Ignored since 0.5.1 (B33-1401). Every product's launch screen
17
+ * is the same Boost33 background, built in. Optional and still typed only so
18
+ * a consumer on `^0.5.0` that passes it keeps compiling; stop passing it.
19
+ */
20
+ stops?: LaunchGradientStops;
17
21
  /**
18
22
  * 0-100, or `null`/omitted while the page has no honest number. Indeterminate
19
23
  * omits `aria-valuenow` entirely: passing 0 to mean "unknown" announces 0%.
@@ -32,7 +36,7 @@ export interface LaunchLoaderProps {
32
36
  */
33
37
  busy?: boolean;
34
38
  /**
35
- * An optional layer painted over the mesh and under the content --
39
+ * An optional layer painted over the glow and under the content --
36
40
  * where an animated backdrop goes. Never required: the screen is complete
37
41
  * without it, and dropped entirely under `prefers-contrast`.
38
42
  */
@@ -47,4 +51,4 @@ export interface LaunchLoaderProps {
47
51
  * No "use client" and no client-only hook: useId is in React's server build, so
48
52
  * this renders -- and its dots animate -- straight from server HTML.
49
53
  */
50
- export declare function LaunchLoader({ caption, stops, progress, dotColor, busy, backdrop, className, }: LaunchLoaderProps): import("react").JSX.Element;
54
+ export declare function LaunchLoader({ caption, progress, dotColor, busy, backdrop, className, }: LaunchLoaderProps): import("react").JSX.Element;
@@ -1,70 +1,57 @@
1
1
  import { jsxs as t, jsx as e } from "react/jsx-runtime";
2
2
  import { useId as m } from "react";
3
- import { DotMatrixLoader as y } from "../DotMatrixLoader/DotMatrixLoader.js";
4
- import { launchRamp as f, launchSolid as x, launchGround as M, LAUNCH_MESH as S, launchShapeStyle as L } from "../../launch-gradient.js";
3
+ import { DotMatrixLoader as h } from "../DotMatrixLoader/DotMatrixLoader.js";
5
4
  import a from "./LaunchLoader.module.css.js";
6
- function I(r) {
7
- return Math.min(100, Math.max(0, r));
5
+ function p(l) {
6
+ return Math.min(100, Math.max(0, l));
8
7
  }
9
- function A({
10
- caption: r,
11
- stops: i,
12
- progress: n = null,
13
- dotColor: c,
14
- busy: h = !0,
8
+ function M({
9
+ caption: l,
10
+ progress: r = null,
11
+ dotColor: n,
12
+ busy: u = !0,
15
13
  backdrop: o,
16
- className: d
14
+ className: s
17
15
  }) {
18
- const s = m(), u = m(), l = typeof n == "number" && Number.isFinite(n) ? Math.round(I(n)) : null, p = f(i), v = {
19
- "--launch-ground": M(i),
20
- "--launch-solid": x(i),
21
- ...c ? { "--launch-accent-input": c } : {}
22
- };
16
+ const d = m(), c = m(), i = typeof r == "number" && Number.isFinite(r) ? Math.round(p(r)) : null, v = n ? { "--launch-accent-input": n } : void 0;
23
17
  return /* @__PURE__ */ t(
24
18
  "div",
25
19
  {
26
- className: d ? `${a.root} ${d}` : a.root,
20
+ className: s ? `${a.root} ${s}` : a.root,
27
21
  style: v,
28
- "aria-busy": h,
29
- "aria-describedby": s,
22
+ "aria-busy": u,
23
+ "aria-describedby": d,
30
24
  "data-launch-loader": "",
31
25
  children: [
32
- /* @__PURE__ */ e("div", { className: a.mesh, "aria-hidden": "true", children: S.map((b, N) => /* @__PURE__ */ e(
33
- "div",
34
- {
35
- className: a.shape,
36
- style: L(b, p)
37
- },
38
- N
39
- )) }),
26
+ /* @__PURE__ */ e("div", { className: a.glow, "aria-hidden": "true" }),
40
27
  o ? /* @__PURE__ */ e("div", { className: a.backdrop, children: o }) : null,
41
28
  /* @__PURE__ */ t("div", { className: a.content, children: [
42
- /* @__PURE__ */ e(y, { label: null, className: a.dots }),
29
+ /* @__PURE__ */ e(h, { label: null, className: a.dots }),
43
30
  /* @__PURE__ */ t(
44
31
  "div",
45
32
  {
46
- id: s,
33
+ id: d,
47
34
  className: a.bar,
48
35
  role: "progressbar",
49
- "aria-labelledby": u,
36
+ "aria-labelledby": c,
50
37
  "aria-valuemin": 0,
51
38
  "aria-valuemax": 100,
52
- "aria-valuenow": l ?? void 0,
53
- "data-indeterminate": l === null,
54
- style: l === null ? void 0 : { "--launch-progress": l },
39
+ "aria-valuenow": i ?? void 0,
40
+ "data-indeterminate": i === null,
41
+ style: i === null ? void 0 : { "--launch-progress": i },
55
42
  children: [
56
43
  /* @__PURE__ */ e("div", { className: a.track }),
57
44
  /* @__PURE__ */ e("div", { className: a.fill })
58
45
  ]
59
46
  }
60
47
  ),
61
- /* @__PURE__ */ e("p", { id: u, className: a.caption, "aria-live": "polite", children: r })
48
+ /* @__PURE__ */ e("p", { id: c, className: a.caption, "aria-live": "polite", children: l })
62
49
  ] })
63
50
  ]
64
51
  }
65
52
  );
66
53
  }
67
54
  export {
68
- A as LaunchLoader
55
+ M as LaunchLoader
69
56
  };
70
57
  //# sourceMappingURL=LaunchLoader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LaunchLoader.js","sources":["../../../src/components/LaunchLoader/LaunchLoader.tsx"],"sourcesContent":["import { useId, type CSSProperties, type ReactNode } from 'react'\nimport { DotMatrixLoader } from '../DotMatrixLoader/DotMatrixLoader'\nimport {\n LAUNCH_MESH,\n launchGround,\n launchRamp,\n launchShapeStyle,\n launchSolid,\n type LaunchGradientStops,\n} from '../../launch-gradient'\nimport styles from './LaunchLoader.module.css'\n\nexport interface LaunchLoaderProps {\n /**\n * What is happening, in words -- \"Opening Boost Score\". It may be one line for\n * the whole launch, which is what the first consumers pass, or rewritten as\n * real milestones land, in which case each rewrite is announced. It is the\n * only text on the screen and the progress bar's name.\n *\n * Taken whole rather than assembled from a destination name, because where a\n * product's name sits in the sentence is the language's to decide, not this\n * package's -- the same reason WalletChip's labels take whole templates.\n */\n caption: string\n /** The destination's four gradient stops, darkest first. See LaunchGradientStops. */\n stops: LaunchGradientStops\n /**\n * 0-100, or `null`/omitted while the page has no honest number. Indeterminate\n * omits `aria-valuenow` entirely: passing 0 to mean \"unknown\" announces 0%.\n * Values outside 0-100 are clamped.\n */\n progress?: number | null\n /**\n * The colour the dots and the bar are drawn in, before blending. Defaults to\n * white, the caption's colour (decided 14 Oct 2026). Both are drawn with\n * `soft-light` at 75% opacity, which a colour passes through too.\n */\n dotColor?: string\n /**\n * Whether the content behind this screen is still loading. Sets `aria-busy`\n * on the root; set it to false the moment the real content lands.\n */\n busy?: boolean\n /**\n * An optional layer painted over the mesh and under the content --\n * where an animated backdrop goes. Never required: the screen is complete\n * without it, and dropped entirely under `prefers-contrast`.\n */\n backdrop?: ReactNode\n className?: string\n}\n\nfunction clampProgress(value: number): number {\n return Math.min(100, Math.max(0, value))\n}\n\n/**\n * The launch screen every product shows while another product opens (B33-1389).\n * Presentational: it knows no product, fetches nothing and owns no timing. The\n * page drives the caption and the progress; this draws them.\n *\n * No \"use client\" and no client-only hook: useId is in React's server build, so\n * this renders -- and its dots animate -- straight from server HTML.\n */\nexport function LaunchLoader({\n caption,\n stops,\n progress = null,\n dotColor,\n busy = true,\n backdrop,\n className,\n}: LaunchLoaderProps) {\n const barId = useId()\n const captionId = useId()\n const determinate = typeof progress === 'number' && Number.isFinite(progress)\n const value = determinate ? Math.round(clampProgress(progress)) : null\n\n const ramp = launchRamp(stops)\n const rootStyle = {\n '--launch-ground': launchGround(stops),\n '--launch-solid': launchSolid(stops),\n ...(dotColor ? { '--launch-accent-input': dotColor } : {}),\n } as CSSProperties\n\n return (\n <div\n className={className ? `${styles.root} ${className}` : styles.root}\n style={rootStyle}\n aria-busy={busy}\n aria-describedby={barId}\n data-launch-loader=\"\"\n >\n {/* The mesh: solid shapes melted by one blur on their container. Every\n shape is styled inline, so the composition paints from the HTML\n alone, in the same chunk as the rest of the component -- on both\n sides of a hop, from the same props. It drifts once and settles back\n on this exact frame (see the module's .mesh rule). */}\n <div className={styles.mesh} aria-hidden=\"true\">\n {LAUNCH_MESH.map((shape, i) => (\n <div\n key={i}\n className={styles.shape}\n style={launchShapeStyle(shape, ramp)}\n />\n ))}\n </div>\n\n {backdrop ? <div className={styles.backdrop}>{backdrop}</div> : null}\n\n <div className={styles.content}>\n {/* Decorative: the caption already says everything the dots do. */}\n {/* Coloured by the .dots class, not DotMatrixLoader's `color` prop: an\n inline colour would outrank the prefers-contrast branch. */}\n <DotMatrixLoader label={null} className={styles.dots} />\n\n {/* Outside the live region on purpose. The caption's region is atomic,\n so a bar inside it would re-announce everything on every tick. */}\n <div\n id={barId}\n className={styles.bar}\n role=\"progressbar\"\n aria-labelledby={captionId}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={value ?? undefined}\n data-indeterminate={value === null}\n style={value === null ? undefined : ({ '--launch-progress': value } as CSSProperties)}\n >\n {/* Separate layers on purpose: the track blends into the mesh, the\n fill does not. A fill inside the track's blend group would blend\n with it and lose the 3:1 it needs against it. */}\n <div className={styles.track} />\n <div className={styles.fill} />\n </div>\n\n {/* The single source of the words: the bar's name and the live region\n in one node, so nothing is read twice.\n\n aria-live stays even though the first consumers pass one static\n line (\"Opening Boost Score\", decided 14 Oct 2026 -- a prerendered\n arrival gives no honest signal for a middle phase). It is inert\n while the text does not change, and it is what makes a changing\n caption announce if a consumer passes one: `caption` is a prop, and\n phased captions are the case this markup was designed for. */}\n <p id={captionId} className={styles.caption} aria-live=\"polite\">\n {caption}\n </p>\n </div>\n </div>\n )\n}\n"],"names":["clampProgress","value","LaunchLoader","caption","stops","progress","dotColor","busy","backdrop","className","barId","useId","captionId","ramp","launchRamp","rootStyle","launchGround","launchSolid","jsxs","styles","jsx","LAUNCH_MESH","shape","i","launchShapeStyle","DotMatrixLoader"],"mappings":";;;;;AAoDA,SAASA,EAAcC,GAAuB;AAC5C,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAGA,CAAK,CAAC;AACzC;AAUO,SAASC,EAAa;AAAA,EAC3B,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,UAAAC;AAAA,EACA,WAAAC;AACF,GAAsB;AACpB,QAAMC,IAAQC,EAAA,GACRC,IAAYD,EAAA,GAEZV,IADc,OAAOI,KAAa,YAAY,OAAO,SAASA,CAAQ,IAChD,KAAK,MAAML,EAAcK,CAAQ,CAAC,IAAI,MAE5DQ,IAAOC,EAAWV,CAAK,GACvBW,IAAY;AAAA,IAChB,mBAAmBC,EAAaZ,CAAK;AAAA,IACrC,kBAAkBa,EAAYb,CAAK;AAAA,IACnC,GAAIE,IAAW,EAAE,yBAAyBA,MAAa,CAAA;AAAA,EAAC;AAG1D,SACE,gBAAAY;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWT,IAAY,GAAGU,EAAO,IAAI,IAAIV,CAAS,KAAKU,EAAO;AAAA,MAC9D,OAAOJ;AAAA,MACP,aAAWR;AAAA,MACX,oBAAkBG;AAAA,MAClB,sBAAmB;AAAA,MAOnB,UAAA;AAAA,QAAA,gBAAAU,EAAC,OAAA,EAAI,WAAWD,EAAO,MAAM,eAAY,QACtC,UAAAE,EAAY,IAAI,CAACC,GAAOC,MACvB,gBAAAH;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAWD,EAAO;AAAA,YAClB,OAAOK,EAAiBF,GAAOT,CAAI;AAAA,UAAA;AAAA,UAF9BU;AAAA,QAAA,CAIR,GACH;AAAA,QAECf,IAAW,gBAAAY,EAAC,OAAA,EAAI,WAAWD,EAAO,UAAW,aAAS,IAAS;AAAA,QAEhE,gBAAAD,EAAC,OAAA,EAAI,WAAWC,EAAO,SAIrB,UAAA;AAAA,UAAA,gBAAAC,EAACK,GAAA,EAAgB,OAAO,MAAM,WAAWN,EAAO,MAAM;AAAA,UAItD,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAIR;AAAA,cACJ,WAAWS,EAAO;AAAA,cAClB,MAAK;AAAA,cACL,mBAAiBP;AAAA,cACjB,iBAAe;AAAA,cACf,iBAAe;AAAA,cACf,iBAAeX,KAAS;AAAA,cACxB,sBAAoBA,MAAU;AAAA,cAC9B,OAAOA,MAAU,OAAO,SAAa,EAAE,qBAAqBA,EAAA;AAAA,cAK5D,UAAA;AAAA,gBAAA,gBAAAmB,EAAC,OAAA,EAAI,WAAWD,EAAO,MAAA,CAAO;AAAA,gBAC9B,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAO,KAAA,CAAM;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAY/B,gBAAAC,EAAC,OAAE,IAAIR,GAAW,WAAWO,EAAO,SAAS,aAAU,UACpD,UAAAhB,EAAA,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"LaunchLoader.js","sources":["../../../src/components/LaunchLoader/LaunchLoader.tsx"],"sourcesContent":["import { useId, type CSSProperties, type ReactNode } from 'react'\nimport { DotMatrixLoader } from '../DotMatrixLoader/DotMatrixLoader'\nimport type { LaunchGradientStops } from '../../launch-gradient'\nimport styles from './LaunchLoader.module.css'\n\nexport interface LaunchLoaderProps {\n /**\n * What is happening, in words -- \"Opening Boost Score\". It may be one line for\n * the whole launch, which is what the first consumers pass, or rewritten as\n * real milestones land, in which case each rewrite is announced. It is the\n * only text on the screen and the progress bar's name.\n *\n * Taken whole rather than assembled from a destination name, because where a\n * product's name sits in the sentence is the language's to decide, not this\n * package's -- the same reason WalletChip's labels take whole templates.\n */\n caption: string\n /**\n * @deprecated Ignored since 0.5.1 (B33-1401). Every product's launch screen\n * is the same Boost33 background, built in. Optional and still typed only so\n * a consumer on `^0.5.0` that passes it keeps compiling; stop passing it.\n */\n stops?: LaunchGradientStops\n /**\n * 0-100, or `null`/omitted while the page has no honest number. Indeterminate\n * omits `aria-valuenow` entirely: passing 0 to mean \"unknown\" announces 0%.\n * Values outside 0-100 are clamped.\n */\n progress?: number | null\n /**\n * The colour the dots and the bar are drawn in, before blending. Defaults to\n * white, the caption's colour (decided 14 Oct 2026). Both are drawn with\n * `soft-light` at 75% opacity, which a colour passes through too.\n */\n dotColor?: string\n /**\n * Whether the content behind this screen is still loading. Sets `aria-busy`\n * on the root; set it to false the moment the real content lands.\n */\n busy?: boolean\n /**\n * An optional layer painted over the glow and under the content --\n * where an animated backdrop goes. Never required: the screen is complete\n * without it, and dropped entirely under `prefers-contrast`.\n */\n backdrop?: ReactNode\n className?: string\n}\n\nfunction clampProgress(value: number): number {\n return Math.min(100, Math.max(0, value))\n}\n\n/**\n * The launch screen every product shows while another product opens (B33-1389).\n * Presentational: it knows no product, fetches nothing and owns no timing. The\n * page drives the caption and the progress; this draws them.\n *\n * No \"use client\" and no client-only hook: useId is in React's server build, so\n * this renders -- and its dots animate -- straight from server HTML.\n */\nexport function LaunchLoader({\n caption,\n progress = null,\n dotColor,\n busy = true,\n backdrop,\n className,\n}: LaunchLoaderProps) {\n const barId = useId()\n const captionId = useId()\n const determinate = typeof progress === 'number' && Number.isFinite(progress)\n const value = determinate ? Math.round(clampProgress(progress)) : null\n\n // `stops` is not read: the background is the same for every product\n // (B33-1401). It is left out of the destructuring above rather than taken\n // and discarded, so nothing here can start depending on it again.\n const rootStyle = dotColor ? ({ '--launch-accent-input': dotColor } as CSSProperties) : undefined\n\n return (\n <div\n className={className ? `${styles.root} ${className}` : styles.root}\n style={rootStyle}\n aria-busy={busy}\n aria-describedby={barId}\n data-launch-loader=\"\"\n >\n {/* The glow: one blurred ellipse of brand orange rising from below the\n middle of the screen, on the root's black. Drawn entirely by the\n stylesheet and taking no prop, so both sides of a hop paint the same\n screen. The old mesh was styled inline only because its colours came\n from props; nothing here does. */}\n <div className={styles.glow} aria-hidden=\"true\" />\n\n {backdrop ? <div className={styles.backdrop}>{backdrop}</div> : null}\n\n <div className={styles.content}>\n {/* Decorative: the caption already says everything the dots do. */}\n {/* Coloured by the .dots class, not DotMatrixLoader's `color` prop: an\n inline colour would outrank the prefers-contrast branch. */}\n <DotMatrixLoader label={null} className={styles.dots} />\n\n {/* Outside the live region on purpose. The caption's region is atomic,\n so a bar inside it would re-announce everything on every tick. */}\n <div\n id={barId}\n className={styles.bar}\n role=\"progressbar\"\n aria-labelledby={captionId}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={value ?? undefined}\n data-indeterminate={value === null}\n style={value === null ? undefined : ({ '--launch-progress': value } as CSSProperties)}\n >\n {/* Separate layers on purpose: the track blends into the glow, the\n fill does not. A fill inside the track's blend group would blend\n with it and lose the 3:1 it needs against it. */}\n <div className={styles.track} />\n <div className={styles.fill} />\n </div>\n\n {/* The single source of the words: the bar's name and the live region\n in one node, so nothing is read twice.\n\n aria-live stays even though the first consumers pass one static\n line (\"Opening Boost Score\", decided 14 Oct 2026 -- a prerendered\n arrival gives no honest signal for a middle phase). It is inert\n while the text does not change, and it is what makes a changing\n caption announce if a consumer passes one: `caption` is a prop, and\n phased captions are the case this markup was designed for. */}\n <p id={captionId} className={styles.caption} aria-live=\"polite\">\n {caption}\n </p>\n </div>\n </div>\n )\n}\n"],"names":["clampProgress","value","LaunchLoader","caption","progress","dotColor","busy","backdrop","className","barId","useId","captionId","rootStyle","jsxs","styles","jsx","DotMatrixLoader"],"mappings":";;;;AAiDA,SAASA,EAAcC,GAAuB;AAC5C,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAGA,CAAK,CAAC;AACzC;AAUO,SAASC,EAAa;AAAA,EAC3B,SAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,UAAAC;AAAA,EACA,WAAAC;AACF,GAAsB;AACpB,QAAMC,IAAQC,EAAA,GACRC,IAAYD,EAAA,GAEZT,IADc,OAAOG,KAAa,YAAY,OAAO,SAASA,CAAQ,IAChD,KAAK,MAAMJ,EAAcI,CAAQ,CAAC,IAAI,MAK5DQ,IAAYP,IAAY,EAAE,yBAAyBA,MAA+B;AAExF,SACE,gBAAAQ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWL,IAAY,GAAGM,EAAO,IAAI,IAAIN,CAAS,KAAKM,EAAO;AAAA,MAC9D,OAAOF;AAAA,MACP,aAAWN;AAAA,MACX,oBAAkBG;AAAA,MAClB,sBAAmB;AAAA,MAOnB,UAAA;AAAA,QAAA,gBAAAM,EAAC,OAAA,EAAI,WAAWD,EAAO,MAAM,eAAY,QAAO;AAAA,QAE/CP,IAAW,gBAAAQ,EAAC,OAAA,EAAI,WAAWD,EAAO,UAAW,aAAS,IAAS;AAAA,QAEhE,gBAAAD,EAAC,OAAA,EAAI,WAAWC,EAAO,SAIrB,UAAA;AAAA,UAAA,gBAAAC,EAACC,GAAA,EAAgB,OAAO,MAAM,WAAWF,EAAO,MAAM;AAAA,UAItD,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAIJ;AAAA,cACJ,WAAWK,EAAO;AAAA,cAClB,MAAK;AAAA,cACL,mBAAiBH;AAAA,cACjB,iBAAe;AAAA,cACf,iBAAe;AAAA,cACf,iBAAeV,KAAS;AAAA,cACxB,sBAAoBA,MAAU;AAAA,cAC9B,OAAOA,MAAU,OAAO,SAAa,EAAE,qBAAqBA,EAAA;AAAA,cAK5D,UAAA;AAAA,gBAAA,gBAAAc,EAAC,OAAA,EAAI,WAAWD,EAAO,MAAA,CAAO;AAAA,gBAC9B,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAO,KAAA,CAAM;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAY/B,gBAAAC,EAAC,OAAE,IAAIJ,GAAW,WAAWG,EAAO,SAAS,aAAU,UACpD,UAAAX,EAAA,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;"}
@@ -1,26 +1,24 @@
1
- const t = "_root_1xhf4_6", o = "_mesh_1xhf4_8", _ = "_shape_1xhf4_81", c = "_backdrop_1xhf4_90", s = "_content_1xhf4_13", n = "_dots_1xhf4_127", a = "_bar_1xhf4_160", h = "_track_1xhf4_168", f = "_fill_1xhf4_176", r = "_caption_1xhf4_202", e = {
2
- root: t,
3
- mesh: o,
4
- shape: _,
5
- backdrop: c,
6
- content: s,
1
+ const o = "_root_1pg11_6", t = "_glow_1pg11_9", _ = "_backdrop_1pg11_103", c = "_content_1pg11_16", n = "_dots_1pg11_139", p = "_bar_1pg11_178", s = "_track_1pg11_186", a = "_fill_1pg11_194", r = "_caption_1pg11_220", g = {
2
+ root: o,
3
+ glow: t,
4
+ backdrop: _,
5
+ content: c,
7
6
  dots: n,
8
- bar: a,
9
- track: h,
10
- fill: f,
7
+ bar: p,
8
+ track: s,
9
+ fill: a,
11
10
  caption: r
12
11
  };
13
12
  export {
14
- c as backdrop,
15
- a as bar,
13
+ _ as backdrop,
14
+ p as bar,
16
15
  r as caption,
17
- s as content,
18
- e as default,
16
+ c as content,
17
+ g as default,
19
18
  n as dots,
20
- f as fill,
21
- o as mesh,
22
- t as root,
23
- _ as shape,
24
- h as track
19
+ a as fill,
20
+ t as glow,
21
+ o as root,
22
+ s as track
25
23
  };
26
24
  //# sourceMappingURL=LaunchLoader.module.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LaunchLoader.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"LaunchLoader.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -28,7 +28,7 @@ export { DotMatrixLoader } from './components/DotMatrixLoader/DotMatrixLoader';
28
28
  export type { DotMatrixLoaderProps } from './components/DotMatrixLoader/DotMatrixLoader';
29
29
  export { LaunchLoader } from './components/LaunchLoader/LaunchLoader';
30
30
  export type { LaunchLoaderProps } from './components/LaunchLoader/LaunchLoader';
31
- export { launchBackdropCss, launchGround, launchSolid } from './launch-gradient';
31
+ export { launchBackdropCss } from './launch-gradient';
32
32
  export type { LaunchGradientStops } from './launch-gradient';
33
33
  export { checkNavHeightBudget, navContentHeight, navBudgetForViewport } from './nav-height-budget';
34
34
  export type { NavHeightBudget, NavRowCosts, NavSectionShape } from './nav-height-budget';
package/dist/index.js CHANGED
@@ -2,43 +2,41 @@
2
2
  import { Sidebar as t } from "./components/Sidebar/Sidebar.js";
3
3
  import { NavSection as a } from "./components/NavSection/NavSection.js";
4
4
  import { Wordmark as f } from "./components/Wordmark/Wordmark.js";
5
- import { BOOST33_MARK_MIN_LEGIBLE_PX as d, Boost33Mark as l } from "./components/Boost33Mark/Boost33Mark.js";
6
- import { ProductMark as c, hasProductMark as i } from "./components/ProductMark/ProductMark.js";
5
+ import { BOOST33_MARK_MIN_LEGIBLE_PX as d, Boost33Mark as h } from "./components/Boost33Mark/Boost33Mark.js";
6
+ import { ProductMark as l, hasProductMark as c } from "./components/ProductMark/ProductMark.js";
7
7
  import { NavItem as n } from "./components/NavItem/NavItem.js";
8
8
  import { WalletChip as L } from "./components/WalletChip/WalletChip.js";
9
- import { defaultWalletChipLabels as k } from "./components/WalletChip/labels.js";
10
- import { TopBar as M } from "./components/TopBar/TopBar.js";
9
+ import { defaultWalletChipLabels as s } from "./components/WalletChip/labels.js";
10
+ import { TopBar as S } from "./components/TopBar/TopBar.js";
11
11
  import { PageHeader as v } from "./components/PageHeader/PageHeader.js";
12
12
  import { AppShell as C } from "./components/AppShell/AppShell.js";
13
13
  import { AppSwitcher as P } from "./components/AppSwitcher/AppSwitcher.js";
14
14
  import { defaultAppSwitcherLabels as b } from "./components/AppSwitcher/labels.js";
15
15
  import { DotMatrixLoader as H } from "./components/DotMatrixLoader/DotMatrixLoader.js";
16
16
  import { LaunchLoader as W } from "./components/LaunchLoader/LaunchLoader.js";
17
- import { launchBackdropCss as G, launchGround as O, launchSolid as T } from "./launch-gradient.js";
18
- import { checkNavHeightBudget as F, navBudgetForViewport as K, navContentHeight as R } from "./nav-height-budget.js";
17
+ import { launchBackdropCss as O } from "./launch-gradient.js";
18
+ import { checkNavHeightBudget as D, navBudgetForViewport as F, navContentHeight as G } from "./nav-height-budget.js";
19
19
  export {
20
20
  C as AppShell,
21
21
  P as AppSwitcher,
22
22
  d as BOOST33_MARK_MIN_LEGIBLE_PX,
23
- l as Boost33Mark,
23
+ h as Boost33Mark,
24
24
  H as DotMatrixLoader,
25
25
  W as LaunchLoader,
26
26
  n as NavItem,
27
27
  a as NavSection,
28
28
  v as PageHeader,
29
- c as ProductMark,
29
+ l as ProductMark,
30
30
  t as Sidebar,
31
- M as TopBar,
31
+ S as TopBar,
32
32
  L as WalletChip,
33
33
  f as Wordmark,
34
- F as checkNavHeightBudget,
34
+ D as checkNavHeightBudget,
35
35
  b as defaultAppSwitcherLabels,
36
- k as defaultWalletChipLabels,
37
- i as hasProductMark,
38
- G as launchBackdropCss,
39
- O as launchGround,
40
- T as launchSolid,
41
- K as navBudgetForViewport,
42
- R as navContentHeight
36
+ s as defaultWalletChipLabels,
37
+ c as hasProductMark,
38
+ O as launchBackdropCss,
39
+ F as navBudgetForViewport,
40
+ G as navContentHeight
43
41
  };
44
42
  //# sourceMappingURL=index.js.map
@@ -1,112 +1,36 @@
1
1
  /**
2
- * The destination product's four gradient stops, ordered darkest first.
3
- *
4
- * The order is a contract, not a style choice, and it carries the screen's
5
- * contrast:
6
- *
7
- * - `stops[0]` is the darkest tone, and the flat colour `prefers-contrast`
8
- * paints.
9
- * - `stops[1]` and the mixes between it and `stops[0]` are the tones behind
10
- * the loader, the bar and the caption. Both must stay at or under relative
11
- * luminance 0.183 (linearised sRGB), the ceiling for white text at 4.5:1:
12
- * the caption sits straight on the mesh with no plate behind it.
13
- * - `stops[2]` is the one light accent, a glow low on the screen, clear of the
14
- * content. `stops[3]` is not painted at all (see launchRamp); it stays in
15
- * the tuple so a palette is still four colours, darkest first.
16
- *
17
- * The values are the consumer's: this package knows no product and holds no
18
- * product's colours (CLAUDE.md). scripts/launch-contrast-check.mts measures the
19
- * composited result behind the content in a real browser.
2
+ * @deprecated Ignored since 0.5.1 (B33-1401). The launch screen is the same
3
+ * Boost33 background for every product, built into `LaunchLoader`, so there are
4
+ * no per-product stops to pass. The type stays so a consumer on `^0.5.0` that
5
+ * still declares its colour map keeps compiling; drop the map and stop passing
6
+ * it.
20
7
  */
21
8
  export type LaunchGradientStops = readonly [string, string, string, string];
22
9
  /**
23
- * The six tones the mesh is painted in, all derived from the four stops, so the
24
- * stops contract and palette-agnosticism both survive. `stops[3]` is not used:
25
- * on Score it is near-white, and it is what blew out every composition that
26
- * included it.
10
+ * The launch screen's ground as a raw CSS string, for a consumer to inline in a
11
+ * `<style>` block with no stylesheet request.
27
12
  *
28
- * The mix percentages are tuned in sRGB to reproduce the three Score mixes
29
- * Jamal approved in Paper on 14 Oct 2026 (recorded on B33-1389) to within a few
30
- * levels a channel; Paper's own figures are not an sRGB mix at round
31
- * percentages. They are mixes rather than hexes so Wallet's greens take the
32
- * same shape.
33
- */
34
- export interface LaunchRamp {
35
- /** stops[0]. The darkest shape. */
36
- r0: string;
37
- r1: string;
38
- /** The mesh's ground, under every shape and behind its blurred edges. */
39
- r2: string;
40
- /** stops[1]. */
41
- r3: string;
42
- r4: string;
43
- /** stops[2]. The one light glow, low on the screen. */
44
- accent: string;
45
- }
46
- export declare function launchRamp(stops: LaunchGradientStops): LaunchRamp;
47
- /**
48
- * One shape in the mesh: a solid tone with an irregular radius, placed and
49
- * sized as a percentage of the mesh container, which overhangs the viewport by
50
- * 12% on every side.
51
- */
52
- export interface LaunchMeshShape {
53
- top: number;
54
- left: number;
55
- width: number;
56
- height: number;
57
- tone: keyof LaunchRamp;
58
- radius: string;
59
- rotate: number;
60
- }
61
- /**
62
- * The composition Jamal approved in Paper on 14 Oct 2026, in paint order. A lit
63
- * left field, a dark diagonal channel through the centre, a soft lit sweep
64
- * down the right edge, one accent glow along the bottom. The dark channel is
65
- * what sits behind the content, so the caption's contrast holds by the
66
- * composition rather than by tuning -- scripts/launch-contrast-check.mts
67
- * measures it.
13
+ * LaunchLoader paints its own background -- black, with one orange glow --
14
+ * from the package stylesheet, identically on both sides of a hub-to-product
15
+ * navigation. This paints the one thing that can show before that stylesheet
16
+ * and the markup arrive: the root in the same black, so the first frame is
17
+ * already the screen's ground rather than white.
68
18
  *
69
- * Solid shapes melted by one blur on their container, not gradients: stacked
70
- * radial-gradients never covered the field, and the ground showing between
71
- * them read as holes. Irregular radii and rotation give the sweeping edges.
72
- */
73
- export declare const LAUNCH_MESH: readonly LaunchMeshShape[];
74
- /**
75
- * One shape's inline style. Built here rather than in the component so the CSS
76
- * it assembles sits beside the rest of the mesh's CSS text, outside the
77
- * no-hardcoded-strings scan of src/components.
78
- */
79
- export declare function launchShapeStyle(shape: LaunchMeshShape, ramp: LaunchRamp): {
80
- top: string;
81
- left: string;
82
- width: string;
83
- height: string;
84
- borderRadius: string;
85
- transform: string | undefined;
86
- background: string;
87
- };
88
- /** How far the mesh container overhangs the viewport on every side, as a fraction of it. */
89
- export declare const LAUNCH_MESH_OVERHANG = 0.12;
90
- /**
91
- * The ground the mesh sits on, as a CSS colour: the tone its blurred edges
92
- * fade into, so the blur never darkens or lightens the viewport's rim.
93
- */
94
- export declare function launchGround(stops: LaunchGradientStops): string;
95
- /** The flat colour `prefers-contrast` paints instead of the gradient: the darkest stop. */
96
- export declare function launchSolid(stops: LaunchGradientStops): string;
97
- /**
98
- * The launch screen's ground as a raw CSS string, for a consumer to inline in
99
- * a `<style>` block with no stylesheet request (B33-1389).
19
+ * `stops` is ignored and kept only so the 0.5.0 call shape,
20
+ * `launchBackdropCss(stops)` or `launchBackdropCss(stops, selector)`, still
21
+ * compiles; `launchBackdropCss()` is the call to write now. `selector` defaults
22
+ * to `html`.
100
23
  *
101
- * The mesh itself is markup -- LaunchLoader renders its shapes with inline
102
- * styles -- so it paints in the same HTML chunk as the component, on both sides
103
- * of a hub-to-product navigation, from the same props: that is what keeps the
104
- * hop seamless now. This paints the one thing that can show before that markup
105
- * parses: the root in the mesh's own ground colour, so the first frame is
106
- * already the screen's base tone rather than white.
24
+ * The `(prefers-contrast)` branch paints the same black the default does. It is
25
+ * redundant today and kept on purpose: it is the branch the component honours
26
+ * too, and keeping the output's shape means the day the two paths differ again
27
+ * is a value change here, not a new rule a consumer has never inlined.
107
28
  *
108
- * `selector` defaults to `html`. The contrast branch is the boolean
109
- * `(prefers-contrast)`, not `(prefers-contrast: more)`, and paints the flat
110
- * darkest stop, as the component does.
29
+ * The selector is the one thing still interpolated. It is the caller's own
30
+ * literal, never served data -- the stops were the value that would have come
31
+ * from a registry, and they are no longer written anywhere -- so it is not
32
+ * checked. Do not feed it from a request.
111
33
  */
112
- export declare function launchBackdropCss(stops: LaunchGradientStops, selector?: string): string;
34
+ export declare function launchBackdropCss(
35
+ /** @deprecated Ignored since 0.5.1. Call `launchBackdropCss()`. */
36
+ _stops?: LaunchGradientStops, selector?: string): string;
@@ -1,60 +1,8 @@
1
- const d = /^[#a-zA-Z0-9(),.%\s/+-]+$/;
2
- function i(t) {
3
- if (t.length !== 4)
4
- throw new Error(`LaunchLoader takes exactly four gradient stops, got ${t.length}`);
5
- for (const r of t)
6
- if (!d.test(r))
7
- throw new Error(`LaunchLoader: ${JSON.stringify(r)} is not a CSS colour this package will inline`);
8
- return t;
9
- }
10
- function u(t) {
11
- const [r, o, e] = i(t), n = (a, h, c) => `color-mix(in srgb, ${a} ${h}%, ${c})`;
12
- return {
13
- r0: r,
14
- r1: n(r, 85, o),
15
- r2: n(r, 67, o),
16
- r3: o,
17
- r4: n(o, 64, e),
18
- accent: e
19
- };
20
- }
21
- const g = [
22
- { top: 40, left: 22, width: 80, height: 58, tone: "r1", radius: "30% 70% 40% 60% / 72% 36% 64% 28%", rotate: -5 },
23
- { top: -20, left: 52, width: 72, height: 66, tone: "r0", radius: "70% 30% 26% 74% / 40% 70% 30% 60%", rotate: 12 },
24
- { top: 4, left: -6, width: 44, height: 42, tone: "r3", radius: "46% 54% 60% 40% / 52% 48% 52% 48%", rotate: 0 },
25
- { top: -24, left: -20, width: 78, height: 56, tone: "r4", radius: "26% 74% 60% 40% / 68% 32% 66% 34%", rotate: -11 },
26
- { top: 64, left: 50, width: 72, height: 56, tone: "accent", radius: "36% 64% 74% 26% / 62% 28% 72% 38%", rotate: 20 },
27
- { top: 64, left: -22, width: 70, height: 52, tone: "r3", radius: "74% 26% 56% 44% / 34% 66% 32% 68%", rotate: -6 },
28
- { top: 4, left: 76, width: 54, height: 88, tone: "r3", radius: "62% 38% 28% 72% / 36% 64% 36% 64%", rotate: -10 },
29
- { top: -22, left: 86, width: 52, height: 54, tone: "r4", radius: "38% 62% 70% 30% / 58% 34% 66% 42%", rotate: 22 }
30
- ];
31
- function s(t, r) {
32
- return {
33
- top: `${t.top}%`,
34
- left: `${t.left}%`,
35
- width: `${t.width}%`,
36
- height: `${t.height}%`,
37
- borderRadius: t.radius,
38
- transform: t.rotate ? `rotate(${t.rotate}deg)` : void 0,
39
- background: r[t.tone]
40
- };
41
- }
42
- function l(t) {
43
- return u(t).r2;
44
- }
45
- function f(t) {
46
- return i(t)[0];
47
- }
48
- function w(t, r = "html") {
49
- const o = l(t), e = f(t);
50
- return `${r}{min-height:100%;background-color:${o}}@media (prefers-contrast){${r}{background-color:${e}}}`;
1
+ const r = "var(--color-neutral-1000,black)";
2
+ function n(c, o = "html") {
3
+ return `${o}{min-height:100%;background-color:${r}}@media (prefers-contrast){${o}{background-color:${r}}}`;
51
4
  }
52
5
  export {
53
- g as LAUNCH_MESH,
54
- w as launchBackdropCss,
55
- l as launchGround,
56
- u as launchRamp,
57
- s as launchShapeStyle,
58
- f as launchSolid
6
+ n as launchBackdropCss
59
7
  };
60
8
  //# sourceMappingURL=launch-gradient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"launch-gradient.js","sources":["../src/launch-gradient.ts"],"sourcesContent":["/*\n * LaunchLoader's background, as data and CSS text (B33-1389). Beside the\n * components rather than inside one, the way nav-height-budget.ts is: it\n * renders nothing, and what it assembles is CSS a consumer inlines, not copy a\n * person reads -- so it sits outside the no-hardcoded-strings scan, which reads\n * src/components for rendered words.\n */\n\n/**\n * The destination product's four gradient stops, ordered darkest first.\n *\n * The order is a contract, not a style choice, and it carries the screen's\n * contrast:\n *\n * - `stops[0]` is the darkest tone, and the flat colour `prefers-contrast`\n * paints.\n * - `stops[1]` and the mixes between it and `stops[0]` are the tones behind\n * the loader, the bar and the caption. Both must stay at or under relative\n * luminance 0.183 (linearised sRGB), the ceiling for white text at 4.5:1:\n * the caption sits straight on the mesh with no plate behind it.\n * - `stops[2]` is the one light accent, a glow low on the screen, clear of the\n * content. `stops[3]` is not painted at all (see launchRamp); it stays in\n * the tuple so a palette is still four colours, darkest first.\n *\n * The values are the consumer's: this package knows no product and holds no\n * product's colours (CLAUDE.md). scripts/launch-contrast-check.mts measures the\n * composited result behind the content in a real browser.\n */\nexport type LaunchGradientStops = readonly [string, string, string, string]\n\n/*\n * A stop is written straight into CSS, and launchBackdropCss's output is meant\n * to be inlined in a <style> block in the first HTML chunk. A value carrying\n * `;`, `{`, `}` or `<` could close the declaration, the rule or the element and\n * write whatever follows. Stops will come from a served registry, not a literal,\n * so this is checked rather than trusted: hex, a colour function, or a keyword,\n * and nothing that can leave the declaration.\n */\nconst SAFE_COLOR = /^[#a-zA-Z0-9(),.%\\s/+-]+$/\n\nfunction checkedStops(stops: LaunchGradientStops): LaunchGradientStops {\n if (stops.length !== 4) {\n throw new Error(`LaunchLoader takes exactly four gradient stops, got ${stops.length}`)\n }\n for (const stop of stops) {\n if (!SAFE_COLOR.test(stop)) {\n throw new Error(`LaunchLoader: ${JSON.stringify(stop)} is not a CSS colour this package will inline`)\n }\n }\n return stops\n}\n\n/**\n * The six tones the mesh is painted in, all derived from the four stops, so the\n * stops contract and palette-agnosticism both survive. `stops[3]` is not used:\n * on Score it is near-white, and it is what blew out every composition that\n * included it.\n *\n * The mix percentages are tuned in sRGB to reproduce the three Score mixes\n * Jamal approved in Paper on 14 Oct 2026 (recorded on B33-1389) to within a few\n * levels a channel; Paper's own figures are not an sRGB mix at round\n * percentages. They are mixes rather than hexes so Wallet's greens take the\n * same shape.\n */\nexport interface LaunchRamp {\n /** stops[0]. The darkest shape. */\n r0: string\n r1: string\n /** The mesh's ground, under every shape and behind its blurred edges. */\n r2: string\n /** stops[1]. */\n r3: string\n r4: string\n /** stops[2]. The one light glow, low on the screen. */\n accent: string\n}\n\nexport function launchRamp(stops: LaunchGradientStops): LaunchRamp {\n const [s0, s1, s2] = checkedStops(stops)\n const mix = (a: string, pc: number, b: string) => `color-mix(in srgb, ${a} ${pc}%, ${b})`\n return {\n r0: s0,\n r1: mix(s0, 85, s1),\n r2: mix(s0, 67, s1),\n r3: s1,\n r4: mix(s1, 64, s2),\n accent: s2,\n }\n}\n\n/**\n * One shape in the mesh: a solid tone with an irregular radius, placed and\n * sized as a percentage of the mesh container, which overhangs the viewport by\n * 12% on every side.\n */\nexport interface LaunchMeshShape {\n top: number\n left: number\n width: number\n height: number\n tone: keyof LaunchRamp\n radius: string\n rotate: number\n}\n\n/**\n * The composition Jamal approved in Paper on 14 Oct 2026, in paint order. A lit\n * left field, a dark diagonal channel through the centre, a soft lit sweep\n * down the right edge, one accent glow along the bottom. The dark channel is\n * what sits behind the content, so the caption's contrast holds by the\n * composition rather than by tuning -- scripts/launch-contrast-check.mts\n * measures it.\n *\n * Solid shapes melted by one blur on their container, not gradients: stacked\n * radial-gradients never covered the field, and the ground showing between\n * them read as holes. Irregular radii and rotation give the sweeping edges.\n */\nexport const LAUNCH_MESH: readonly LaunchMeshShape[] = [\n { top: 40, left: 22, width: 80, height: 58, tone: 'r1', radius: '30% 70% 40% 60% / 72% 36% 64% 28%', rotate: -5 },\n { top: -20, left: 52, width: 72, height: 66, tone: 'r0', radius: '70% 30% 26% 74% / 40% 70% 30% 60%', rotate: 12 },\n { top: 4, left: -6, width: 44, height: 42, tone: 'r3', radius: '46% 54% 60% 40% / 52% 48% 52% 48%', rotate: 0 },\n { top: -24, left: -20, width: 78, height: 56, tone: 'r4', radius: '26% 74% 60% 40% / 68% 32% 66% 34%', rotate: -11 },\n { top: 64, left: 50, width: 72, height: 56, tone: 'accent', radius: '36% 64% 74% 26% / 62% 28% 72% 38%', rotate: 20 },\n { top: 64, left: -22, width: 70, height: 52, tone: 'r3', radius: '74% 26% 56% 44% / 34% 66% 32% 68%', rotate: -6 },\n { top: 4, left: 76, width: 54, height: 88, tone: 'r3', radius: '62% 38% 28% 72% / 36% 64% 36% 64%', rotate: -10 },\n { top: -22, left: 86, width: 52, height: 54, tone: 'r4', radius: '38% 62% 70% 30% / 58% 34% 66% 42%', rotate: 22 },\n]\n\n/**\n * One shape's inline style. Built here rather than in the component so the CSS\n * it assembles sits beside the rest of the mesh's CSS text, outside the\n * no-hardcoded-strings scan of src/components.\n */\nexport function launchShapeStyle(shape: LaunchMeshShape, ramp: LaunchRamp) {\n return {\n top: `${shape.top}%`,\n left: `${shape.left}%`,\n width: `${shape.width}%`,\n height: `${shape.height}%`,\n borderRadius: shape.radius,\n transform: shape.rotate ? `rotate(${shape.rotate}deg)` : undefined,\n background: ramp[shape.tone],\n }\n}\n\n/** How far the mesh container overhangs the viewport on every side, as a fraction of it. */\nexport const LAUNCH_MESH_OVERHANG = 0.12\n\n/**\n * The ground the mesh sits on, as a CSS colour: the tone its blurred edges\n * fade into, so the blur never darkens or lightens the viewport's rim.\n */\nexport function launchGround(stops: LaunchGradientStops): string {\n return launchRamp(stops).r2\n}\n\n/** The flat colour `prefers-contrast` paints instead of the gradient: the darkest stop. */\nexport function launchSolid(stops: LaunchGradientStops): string {\n return checkedStops(stops)[0]\n}\n\n/**\n * The launch screen's ground as a raw CSS string, for a consumer to inline in\n * a `<style>` block with no stylesheet request (B33-1389).\n *\n * The mesh itself is markup -- LaunchLoader renders its shapes with inline\n * styles -- so it paints in the same HTML chunk as the component, on both sides\n * of a hub-to-product navigation, from the same props: that is what keeps the\n * hop seamless now. This paints the one thing that can show before that markup\n * parses: the root in the mesh's own ground colour, so the first frame is\n * already the screen's base tone rather than white.\n *\n * `selector` defaults to `html`. The contrast branch is the boolean\n * `(prefers-contrast)`, not `(prefers-contrast: more)`, and paints the flat\n * darkest stop, as the component does.\n */\nexport function launchBackdropCss(stops: LaunchGradientStops, selector = 'html'): string {\n const ground = launchGround(stops)\n const solid = launchSolid(stops)\n return `${selector}{min-height:100%;background-color:${ground}}` + `@media (prefers-contrast){${selector}{background-color:${solid}}}`\n}\n"],"names":["SAFE_COLOR","checkedStops","stops","stop","launchRamp","s0","s1","s2","mix","pc","b","LAUNCH_MESH","launchShapeStyle","shape","ramp","launchGround","launchSolid","launchBackdropCss","selector","ground","solid"],"mappings":"AAsCA,MAAMA,IAAa;AAEnB,SAASC,EAAaC,GAAiD;AACrE,MAAIA,EAAM,WAAW;AACnB,UAAM,IAAI,MAAM,uDAAuDA,EAAM,MAAM,EAAE;AAEvF,aAAWC,KAAQD;AACjB,QAAI,CAACF,EAAW,KAAKG,CAAI;AACvB,YAAM,IAAI,MAAM,iBAAiB,KAAK,UAAUA,CAAI,CAAC,+CAA+C;AAGxG,SAAOD;AACT;AA2BO,SAASE,EAAWF,GAAwC;AACjE,QAAM,CAACG,GAAIC,GAAIC,CAAE,IAAIN,EAAaC,CAAK,GACjCM,IAAM,CAAC,GAAWC,GAAYC,MAAc,sBAAsB,CAAC,IAAID,CAAE,MAAMC,CAAC;AACtF,SAAO;AAAA,IACL,IAAIL;AAAA,IACJ,IAAIG,EAAIH,GAAI,IAAIC,CAAE;AAAA,IAClB,IAAIE,EAAIH,GAAI,IAAIC,CAAE;AAAA,IAClB,IAAIA;AAAA,IACJ,IAAIE,EAAIF,GAAI,IAAIC,CAAE;AAAA,IAClB,QAAQA;AAAA,EAAA;AAEZ;AA6BO,MAAMI,IAA0C;AAAA,EACrD,EAAE,KAAK,IAAI,MAAM,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM,MAAM,QAAQ,qCAAqC,QAAQ,GAAA;AAAA,EAC7G,EAAE,KAAK,KAAK,MAAM,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM,MAAM,QAAQ,qCAAqC,QAAQ,GAAA;AAAA,EAC9G,EAAE,KAAK,GAAG,MAAM,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM,MAAM,QAAQ,qCAAqC,QAAQ,EAAA;AAAA,EAC5G,EAAE,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,QAAQ,IAAI,MAAM,MAAM,QAAQ,qCAAqC,QAAQ,IAAA;AAAA,EAC/G,EAAE,KAAK,IAAI,MAAM,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM,UAAU,QAAQ,qCAAqC,QAAQ,GAAA;AAAA,EACjH,EAAE,KAAK,IAAI,MAAM,KAAK,OAAO,IAAI,QAAQ,IAAI,MAAM,MAAM,QAAQ,qCAAqC,QAAQ,GAAA;AAAA,EAC9G,EAAE,KAAK,GAAG,MAAM,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM,MAAM,QAAQ,qCAAqC,QAAQ,IAAA;AAAA,EAC5G,EAAE,KAAK,KAAK,MAAM,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM,MAAM,QAAQ,qCAAqC,QAAQ,GAAA;AAChH;AAOO,SAASC,EAAiBC,GAAwBC,GAAkB;AACzE,SAAO;AAAA,IACL,KAAK,GAAGD,EAAM,GAAG;AAAA,IACjB,MAAM,GAAGA,EAAM,IAAI;AAAA,IACnB,OAAO,GAAGA,EAAM,KAAK;AAAA,IACrB,QAAQ,GAAGA,EAAM,MAAM;AAAA,IACvB,cAAcA,EAAM;AAAA,IACpB,WAAWA,EAAM,SAAS,UAAUA,EAAM,MAAM,SAAS;AAAA,IACzD,YAAYC,EAAKD,EAAM,IAAI;AAAA,EAAA;AAE/B;AASO,SAASE,EAAab,GAAoC;AAC/D,SAAOE,EAAWF,CAAK,EAAE;AAC3B;AAGO,SAASc,EAAYd,GAAoC;AAC9D,SAAOD,EAAaC,CAAK,EAAE,CAAC;AAC9B;AAiBO,SAASe,EAAkBf,GAA4BgB,IAAW,QAAgB;AACvF,QAAMC,IAASJ,EAAab,CAAK,GAC3BkB,IAAQJ,EAAYd,CAAK;AAC/B,SAAO,GAAGgB,CAAQ,qCAAqCC,CAAM,8BAAmCD,CAAQ,qBAAqBE,CAAK;AACpI;"}
1
+ {"version":3,"file":"launch-gradient.js","sources":["../src/launch-gradient.ts"],"sourcesContent":["/*\n * LaunchLoader's backdrop CSS, as text (B33-1389, B33-1401). Beside the\n * components rather than inside one, the way nav-height-budget.ts is: it\n * renders nothing, and what it assembles is CSS a consumer inlines, not copy a\n * person reads -- so it sits outside the no-hardcoded-strings scan, which reads\n * src/components for rendered words.\n */\n\n/**\n * @deprecated Ignored since 0.5.1 (B33-1401). The launch screen is the same\n * Boost33 background for every product, built into `LaunchLoader`, so there are\n * no per-product stops to pass. The type stays so a consumer on `^0.5.0` that\n * still declares its colour map keeps compiling; drop the map and stop passing\n * it.\n */\nexport type LaunchGradientStops = readonly [string, string, string, string]\n\n/*\n * The ground every launch screen is painted on: --color-neutral-1000, the\n * charte's primary black, which tokens.css reserves for \"the logo and dark\n * ground\". Written as the token with a keyword fallback, because this string is\n * inlined in the first HTML chunk precisely so it paints before any stylesheet\n * arrives -- and before one arrives, the token does not exist. `black` is the\n * same value tokens.css declares for it (tests/launch-loader.test.tsx holds the\n * two together); a keyword rather than a hex because no hex lives in src/\n * outside the token sheets (tests/guards.test.ts).\n */\nconst LAUNCH_GROUND = 'var(--color-neutral-1000,black)'\n\n/**\n * The launch screen's ground as a raw CSS string, for a consumer to inline in a\n * `<style>` block with no stylesheet request.\n *\n * LaunchLoader paints its own background -- black, with one orange glow --\n * from the package stylesheet, identically on both sides of a hub-to-product\n * navigation. This paints the one thing that can show before that stylesheet\n * and the markup arrive: the root in the same black, so the first frame is\n * already the screen's ground rather than white.\n *\n * `stops` is ignored and kept only so the 0.5.0 call shape,\n * `launchBackdropCss(stops)` or `launchBackdropCss(stops, selector)`, still\n * compiles; `launchBackdropCss()` is the call to write now. `selector` defaults\n * to `html`.\n *\n * The `(prefers-contrast)` branch paints the same black the default does. It is\n * redundant today and kept on purpose: it is the branch the component honours\n * too, and keeping the output's shape means the day the two paths differ again\n * is a value change here, not a new rule a consumer has never inlined.\n *\n * The selector is the one thing still interpolated. It is the caller's own\n * literal, never served data -- the stops were the value that would have come\n * from a registry, and they are no longer written anywhere -- so it is not\n * checked. Do not feed it from a request.\n */\nexport function launchBackdropCss(\n /** @deprecated Ignored since 0.5.1. Call `launchBackdropCss()`. */\n _stops?: LaunchGradientStops,\n selector = 'html',\n): string {\n return (\n `${selector}{min-height:100%;background-color:${LAUNCH_GROUND}}` +\n `@media (prefers-contrast){${selector}{background-color:${LAUNCH_GROUND}}}`\n )\n}\n"],"names":["LAUNCH_GROUND","launchBackdropCss","_stops","selector"],"mappings":"AA2BA,MAAMA,IAAgB;AA2Bf,SAASC,EAEdC,GACAC,IAAW,QACH;AACR,SACE,GAAGA,CAAQ,qCAAqCH,CAAa,8BAChCG,CAAQ,qBAAqBH,CAAa;AAE3E;"}
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .btn-primary,.btn-quiet,.btn-danger{cursor:pointer;transition:background-color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),transform var(--dur-instant) var(--ease-out)}.btn-primary{border:none;background:var(--color-primary);color:var(--color-primary-foreground)}.btn-primary:hover:not(:disabled){background:var(--color-primary-hover)}.btn-quiet{background:transparent;color:var(--color-foreground-secondary)}.btn-quiet:hover:not(:disabled){background:var(--color-surface-muted)}.btn-danger{border:1px solid var(--color-danger);background:var(--color-danger);color:var(--color-neutral-0)}.btn-danger:hover:not(:disabled){border-color:color-mix(in srgb,var(--color-danger) 85%,var(--color-neutral-950));background:color-mix(in srgb,var(--color-danger) 85%,var(--color-neutral-950))}.btn-primary:disabled,.btn-quiet:disabled,.btn-danger:disabled{opacity:.55;cursor:not-allowed}.spinner{box-sizing:border-box;width:var(--spacing-4_5);height:var(--spacing-4_5);border:2px solid var(--color-neutral-0);border-right-color:transparent;border-radius:var(--radius-full);animation:boost33-spin var(--dur-spin) linear infinite}.spinner--sm{width:var(--spacing-3_5);height:var(--spacing-3_5)}.spinner--primary{border-color:var(--color-primary);border-right-color:transparent}@keyframes boost33-spin{to{transform:rotate(360deg)}}.sk{display:block;border-radius:var(--radius-md);background:var(--color-surface-muted);animation:boost33-pulse var(--dur-pulse) ease-in-out infinite}.sk-group{animation:boost33-appear var(--dur-base) var(--ease-out) var(--dur-fast) both}.reveal{animation:boost33-appear var(--dur-base) var(--ease-out) both}@keyframes boost33-pulse{50%{opacity:.55}}@keyframes boost33-appear{0%{opacity:0}}@media(prefers-reduced-motion:no-preference){.btn-primary:active:not(:disabled),.btn-quiet:active:not(:disabled),.btn-danger:active:not(:disabled){transform:scale(.98)}}@media(prefers-reduced-motion:reduce){.sk,.sk-group,.reveal,.spinner{animation:none}*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:0s!important;scroll-behavior:auto!important}}._sidebar_17kel_7{display:flex;flex-direction:column;box-sizing:border-box;width:var(--container-sidebar);height:100%;padding-inline:var(--spacing-3);border-right:1px solid var(--color-border);background:var(--color-background);font-family:var(--font-sans)}._sidebar_17kel_7[data-collapsed=true]{width:var(--container-sidebar-rail)}._sidebar_17kel_7>nav{flex-shrink:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;margin:calc(-1 * var(--spacing-1));padding:var(--spacing-1);scroll-padding:var(--spacing-1)}@media(prefers-reduced-motion:reduce){._sidebar_17kel_7>nav{scroll-behavior:auto}}._section_3sxsg_5{display:flex;flex-direction:column}._header_3sxsg_13{margin:0;padding:var(--spacing-2) var(--spacing-2_5);color:var(--color-foreground-muted);font-family:var(--font-sans);font-size:var(--text-2xs);font-weight:var(--font-weight-semibold);letter-spacing:var(--tracking-caps);text-transform:uppercase}._wordmark_1k88r_4{display:flex;align-items:center;gap:var(--spacing-2_5);font-family:var(--font-display)}._mark_1k88r_17{display:inline-flex;flex:0 0 var(--spacing-6);align-items:center;justify-content:center;width:var(--spacing-6);height:var(--spacing-6)}._mark_1k88r_17 svg{width:100%;height:100%}._name_1k88r_35{color:var(--color-foreground);font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--font-weight-semibold);letter-spacing:var(--tracking-tight)}._wordmark_1k88r_4[data-collapsed=true] ._name_1k88r_35{position:absolute;overflow:hidden;clip-path:inset(50%);width:1px;height:1px;white-space:nowrap}._wordmark_1k88r_4[data-collapsed=true]{justify-content:center}._tile_5vhrh_12{fill:var(--color-neutral-950)}._ring_5vhrh_16{fill:var(--color-primary)}._mark_5vhrh_24{display:block}._mark_1jt5g_6{display:block}._ground_1jt5g_17{rx:var(--radius-product-tile)}._row_w21mf_4{display:flex;align-items:center;width:100%;gap:var(--spacing-2_5);padding:var(--spacing-2) var(--spacing-2_5);border:none;border-radius:var(--radius-lg);background:transparent;font-family:var(--font-sans);text-align:left;text-decoration:none;cursor:pointer;transition:background-color var(--dur-fast) var(--ease-out)}._row_w21mf_4:hover{background:var(--color-surface-muted)}._row_w21mf_4[data-active=true]{background:var(--color-surface)}._row_w21mf_4:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}._icon_w21mf_41{display:inline-flex;flex:0 0 var(--spacing-4);align-items:center;justify-content:center;width:var(--spacing-4);height:var(--spacing-4);color:var(--color-foreground-secondary)}._icon_w21mf_41 svg{width:100%;height:100%}._row_w21mf_4[data-active=true] ._icon_w21mf_41{color:var(--color-foreground)}._row_w21mf_4[data-collapsed=true]{justify-content:center}._label_w21mf_66{flex:1 1 auto;min-width:0;overflow:hidden;color:var(--color-foreground-secondary);font-size:var(--text-nav-label);font-weight:var(--font-weight-regular);text-overflow:ellipsis;white-space:nowrap}._row_w21mf_4[data-active=true] ._label_w21mf_66{color:var(--color-foreground);font-weight:var(--font-weight-semibold)}._row_w21mf_4[data-collapsed=true] ._label_w21mf_66{position:absolute;overflow:hidden;clip-path:inset(50%);width:1px;height:1px;white-space:nowrap}._trailingSlot_w21mf_92{display:flex;flex:0 0 var(--spacing-5_5);align-items:center;justify-content:center;width:var(--spacing-5_5);font-family:var(--font-sans);font-size:var(--text-nav-label)}._row_w21mf_4[data-collapsed=true] ._trailingSlot_w21mf_92{display:none}._count_w21mf_106{color:var(--color-foreground-muted)}._countUrgent_w21mf_110{color:var(--color-primary)}@media(prefers-reduced-motion:reduce){._row_w21mf_4{transition:none}}._chip_xxga2_37{--chip-lift: 0px;position:relative;box-sizing:border-box;width:100%;padding:calc(var(--spacing-3) + var(--chip-lift));border:1px solid var(--color-border);border-radius:var(--radius-2xl);background:transparent;font-family:var(--font-sans)}._chip_xxga2_37:not([data-unknown]):hover,._chip_xxga2_37:not([data-unknown]):focus-within,._chip_xxga2_37[data-threshold]{--chip-lift: var(--spacing-0_5);box-shadow:var(--shadow-overlay)}._chip_xxga2_37:not([data-threshold]):not([data-unknown]):hover,._chip_xxga2_37:not([data-threshold]):not([data-unknown]):focus-within{background:var(--color-surface)}._chip_xxga2_37:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}._header_xxga2_74{display:flex;align-items:center;gap:var(--spacing-2)}._chip_xxga2_37:not([data-threshold]):not([data-unknown]) ._header_xxga2_74{padding-right:var(--spacing-topup-reserve)}._name_xxga2_83{min-width:0;overflow:hidden;color:var(--color-foreground-muted);font-size:var(--text-xs);font-weight:var(--font-weight-medium);line-height:var(--leading-tight);text-overflow:ellipsis;white-space:nowrap}._pill_xxga2_162{padding:var(--spacing-0_5) var(--spacing-2);border-radius:var(--radius-full);background:var(--color-warning-subtle);color:var(--color-warning);font-size:var(--text-2xs);font-weight:var(--font-weight-semibold)}._figure_xxga2_171{display:flex;align-items:baseline;gap:var(--spacing-1_5);margin-top:calc(var(--spacing-2_5) + var(--chip-lift))}._amount_xxga2_186{color:var(--color-foreground);font-family:var(--font-mono);font-size:var(--text-2xl);font-weight:var(--font-weight-bold);letter-spacing:var(--tracking-tight);line-height:var(--leading-none)}._unit_xxga2_195{color:var(--color-foreground-muted);font-size:var(--text-xs)}._retry_xxga2_200{width:var(--spacing-3);height:var(--spacing-3);color:var(--color-foreground-muted)}._bar_xxga2_209{display:flex;overflow:hidden;width:100%;height:calc(var(--spacing-1_25) + var(--chip-lift));margin-top:calc(var(--spacing-2_5) + var(--chip-lift));border-radius:var(--radius-full)}._bar_xxga2_209[data-tone=rest]{background:var(--color-surface-muted)}._bar_xxga2_209[data-tone=threshold]{background:var(--color-warning-subtle)}._bar_xxga2_209[data-tone=unknown]{background:var(--color-surface-muted)}._segmentGranted_xxga2_230,._segmentPurchased_xxga2_231{height:100%;transition:width var(--dur-fast) var(--ease-out)}._segmentGranted_xxga2_230{background:var(--color-grant)}._segmentPurchased_xxga2_231{background:var(--color-purchased)}._details_xxga2_275{display:none}._chip_xxga2_37:hover ._details_xxga2_275,._chip_xxga2_37:focus-within ._details_xxga2_275{display:block}._split_xxga2_284{display:flex;flex-direction:column;gap:var(--spacing-1);margin:var(--spacing-2_5) 0 0}._splitRow_xxga2_291{display:flex;align-items:center;justify-content:space-between}._splitLabel_xxga2_297{display:flex;align-items:center;gap:var(--spacing-1_5);color:var(--color-foreground);font-size:var(--text-xs)}._splitAmount_xxga2_305{margin:0;color:var(--color-foreground);font-family:var(--font-mono);font-size:var(--text-xs);font-variant-numeric:tabular-nums}._dotGranted_xxga2_313,._dotPurchased_xxga2_314{width:var(--spacing-1_5);height:var(--spacing-1_5);border-radius:var(--radius-full)}._dotGranted_xxga2_313{background:var(--color-grant)}._dotPurchased_xxga2_314{background:var(--color-purchased)}._footer_xxga2_328{margin:var(--spacing-3) 0 0;padding-top:var(--spacing-1);border-top:1px solid var(--color-border);color:var(--color-foreground-muted);font-size:var(--text-2xs)}._burnNote_xxga2_336{margin:var(--spacing-2_5) 0 0;color:var(--color-foreground-secondary);font-size:var(--text-2xs);line-height:var(--leading-snug)}._topUp_xxga2_87{position:absolute;top:calc(var(--spacing-3) + var(--chip-lift));right:calc(var(--spacing-3) + var(--chip-lift));padding:0;border:none;background:transparent;color:var(--color-primary);font-family:var(--font-sans);font-size:var(--text-xs);font-weight:var(--font-weight-semibold);opacity:0;cursor:pointer;transition:opacity var(--dur-fast) var(--ease-out)}._chip_xxga2_37:hover ._topUp_xxga2_87,._chip_xxga2_37:focus-within ._topUp_xxga2_87,._topUp_xxga2_87:focus-visible{opacity:1}._topUp_xxga2_87:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}._topUp_xxga2_87[data-grown=true]{position:static;width:100%;margin-top:var(--spacing-2_5);padding:var(--spacing-2);border-radius:var(--radius-lg);background:var(--color-primary);color:var(--color-primary-foreground);font-size:var(--text-sm);opacity:1}._topUp_xxga2_87[data-grown=true]:hover{background:var(--color-primary-hover)}._rail_xxga2_402{--chip-lift: 0px;position:relative;display:flex;box-sizing:border-box;width:100%;flex-direction:column;align-items:center;gap:var(--spacing-2);padding:var(--spacing-2);font-family:var(--font-sans)}._railIcon_xxga2_416{width:var(--spacing-6);height:var(--spacing-6);color:var(--color-foreground-secondary)}._railFigure_xxga2_422{color:var(--color-foreground);font-family:var(--font-mono);font-size:var(--text-sm);font-weight:var(--font-weight-semibold);font-variant-numeric:tabular-nums}._rail_xxga2_402 ._bar_xxga2_209{height:var(--spacing-0_5);margin-top:0}._srOnly_xxga2_435{position:absolute;overflow:hidden;clip-path:inset(50%);width:1px;height:1px;white-space:nowrap}@media(prefers-reduced-motion:reduce){._segmentGranted_xxga2_230,._segmentPurchased_xxga2_231,._topUp_xxga2_87{transition:none}}._bar_194bx_7{display:flex;align-items:center;justify-content:space-between;gap:var(--spacing-4);box-sizing:border-box;height:var(--spacing-12);padding:0 var(--spacing-8);border-bottom:1px solid var(--color-border);background:var(--color-surface);font-family:var(--font-sans)}._breadcrumb_194bx_20{display:flex;min-width:0;align-items:center;gap:var(--spacing-2);overflow:hidden;color:var(--color-foreground);font-size:var(--text-sm);font-weight:var(--font-weight-medium);text-overflow:ellipsis;white-space:nowrap}._actions_194bx_33{display:flex;flex:0 0 auto;align-items:center;gap:var(--spacing-2)}@supports (animation-timeline: --a) and (timeline-scope: --a){@container style(--boost33-shell-timeline: on){._bar_194bx_7{position:relative;z-index:1;animation:_scrolled_194bx_1 linear both;animation-timeline:--boost33-shell-scroll;animation-range:0 var(--spacing-10)}}}@keyframes _scrolled_194bx_1{to{box-shadow:var(--shadow-scrolled)}}._header_i17td_42{display:flex;align-items:center;justify-content:space-between;gap:var(--spacing-8);padding:var(--spacing-4_5) var(--spacing-8) var(--spacing-4);background:var(--color-surface);font-family:var(--font-sans)}._headings_i17td_52{display:flex;min-width:0;flex-direction:column;gap:var(--spacing-1)}._title_i17td_33{margin:0;color:var(--color-foreground);font-family:var(--font-display);font-size:var(--text-2xl);font-weight:var(--font-weight-semibold);letter-spacing:var(--tracking-tight);line-height:var(--leading-tight)}._subtitle_i17td_74{margin:0;color:var(--color-foreground-secondary);font-size:var(--text-base);font-weight:var(--font-weight-regular);line-height:var(--leading-snug)}._actions_i17td_82{display:flex;flex:0 0 auto;align-items:center;gap:var(--spacing-2)}._shell_10chf_10{display:flex;height:100%;background:var(--color-surface);font-family:var(--font-sans)}._wordmark_10chf_20{padding:var(--spacing-3) var(--spacing-2_5) var(--spacing-5)}._switcher_10chf_26{padding-bottom:var(--spacing-4)}._foot_10chf_33{display:flex;flex-direction:column;gap:var(--spacing-4);margin-block-start:auto;padding-block-start:var(--spacing-4)}._nav_10chf_45{display:flex;flex-direction:column;gap:var(--spacing-4)}._main_10chf_54{display:flex;min-width:0;flex:1;flex-direction:column}._content_10chf_75{flex:1;min-height:0;overflow-y:auto;background:var(--color-surface)}@supports (animation-timeline: --a) and (timeline-scope: --a){._main_10chf_54{timeline-scope:--boost33-shell-scroll;--boost33-shell-timeline: on}._content_10chf_75{scroll-timeline:--boost33-shell-scroll block}}:root{--shadow-overlay: 0px 16px 40px -10px var(--shadow-overlay-color);--shadow-lift: 0px 10px 24px -14px color-mix(in srgb, var(--color-neutral-950) 28%, transparent);--shadow-scrolled: 0px 6px 16px -12px color-mix(in srgb, var(--color-neutral-950) 35%, transparent)}._root_15f7d_8{position:relative;font-family:var(--font-sans)}._trigger_15f7d_17{display:flex;box-sizing:border-box;width:100%;align-items:center;gap:var(--spacing-2);padding:var(--spacing-2_25) var(--spacing-2);border:1px solid var(--color-border-strong);border-radius:var(--radius-lg);background:transparent;font-family:var(--font-sans);cursor:pointer}._trigger_15f7d_17[aria-expanded=true]{background:var(--color-surface-muted)}._trigger_15f7d_17:focus-visible,._railTrigger_15f7d_46:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}._triggerName_15f7d_56{overflow:hidden;flex:1;color:var(--color-foreground);font-size:var(--text-nav-label);font-weight:var(--font-weight-semibold);text-align:left;text-overflow:ellipsis;white-space:nowrap}._chevron_15f7d_67{width:var(--spacing-3);height:var(--spacing-3);flex-shrink:0;color:var(--color-foreground-muted);transition:transform var(--dur-fast) var(--ease-out)}._trigger_15f7d_17[aria-expanded=true] ._chevron_15f7d_67{transform:rotate(180deg)}._railTrigger_15f7d_46{display:flex;box-sizing:border-box;width:100%;min-height:var(--spacing-6);align-items:flex-start;justify-content:center;padding:0;border:none;background:transparent;cursor:pointer}._panel_15f7d_109{position:absolute;z-index:1;top:100%;left:0;width:var(--container-sidebar);box-sizing:border-box;margin-top:var(--spacing-0_5);padding:var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--radius-2xl);background:var(--color-surface);box-shadow:var(--shadow-overlay)}._hubRow_15f7d_135,._productRow_15f7d_136,._accountRow_15f7d_137{display:flex;box-sizing:border-box;width:100%;align-items:center;gap:var(--spacing-2_5);padding:var(--spacing-2);border:none;border-radius:var(--radius-lg);background:transparent;color:var(--color-foreground);font-family:var(--font-sans);text-align:left;text-decoration:none;cursor:pointer}._hubRow_15f7d_135:hover,._productRow_15f7d_136:hover,._accountRow_15f7d_137:hover{background:var(--color-surface-muted)}._hubRow_15f7d_135:focus-visible,._productRow_15f7d_136:focus-visible,._accountRow_15f7d_137:focus-visible{outline:2px solid var(--color-primary);outline-offset:-2px}._products_15f7d_144{display:flex;flex-direction:column;gap:var(--spacing-0_5);margin:0;padding:0;list-style:none}._productRow_15f7d_136[data-current=true]{background:var(--color-surface-muted)}._productRow_15f7d_136[data-entitled=false] ._rowName_15f7d_193{color:var(--color-foreground-muted)}._accountRow_15f7d_137{padding-inline:var(--spacing-3)}._accountRow_15f7d_137 ._rowName_15f7d_193{font-size:var(--text-sm)}._accountRow_15f7d_137 ._rowSub_15f7d_213{font-size:var(--text-2xs)}._accountRow_15f7d_137[data-actionable=false]{cursor:default}._accountRow_15f7d_137[data-actionable=false]:hover{background:transparent}._rowText_15f7d_238{display:flex;min-width:0;flex-direction:column}._hubRow_15f7d_135 ._rowText_15f7d_238{gap:var(--spacing-0_5)}._rowName_15f7d_193{overflow:hidden;color:var(--color-foreground);font-size:var(--text-nav-label);font-weight:var(--font-weight-regular);text-overflow:ellipsis;white-space:nowrap}._productRow_15f7d_136 ._rowName_15f7d_193{flex:1}._rowSub_15f7d_213{overflow:hidden;color:var(--color-foreground-muted);font-size:var(--text-xs);text-overflow:ellipsis;white-space:nowrap}._hubMark_15f7d_281{width:var(--spacing-5);height:var(--spacing-5);flex-shrink:0;color:var(--color-foreground)}._tag_15f7d_297{flex-shrink:0;margin-left:auto;padding:var(--spacing-0_5) var(--spacing-1_5);border-radius:var(--radius-full);background:var(--color-surface-muted);color:var(--color-foreground-muted);font-size:var(--text-2xs);font-weight:var(--font-weight-medium)}._check_15f7d_308{width:var(--spacing-4);height:var(--spacing-4);flex-shrink:0;margin-left:auto;color:var(--color-foreground)}._avatar_15f7d_321{display:grid;width:var(--spacing-6);height:var(--spacing-6);flex-shrink:0;border-radius:var(--radius-lg);background:var(--color-surface-muted);color:var(--color-foreground-secondary);font-size:var(--text-3xs);font-weight:var(--font-weight-semibold);place-items:center}._chevronRight_15f7d_334{width:var(--spacing-4);height:var(--spacing-4);flex-shrink:0;margin-left:auto;color:var(--color-foreground-muted)}._divider_15f7d_355{margin:var(--spacing-2_25) 0 var(--spacing-2);border:none;border-top:1px solid var(--color-border)}._products_15f7d_144+._divider_15f7d_355{margin:var(--spacing-1_5) 0 var(--spacing-1)}@media(prefers-reduced-motion:reduce){._chevron_15f7d_67{transition:none}}._root_g1823_11{--dots-size: var(--spacing-8);--dots-speed: var(--dur-dots);--dots-ease: var(--ease-in-out-quint);--dots-gap: calc(var(--dots-size) * .14);--dots-dot: calc((var(--dots-size) - var(--dots-gap) * 2) / 3);display:inline-flex;align-items:center;justify-content:center}._grid_g1823_25{display:grid;gap:var(--dots-gap);grid-template-columns:repeat(3,var(--dots-dot))}._dot_g1823_31{width:var(--dots-dot);height:var(--dots-dot);border-radius:var(--radius-full);background:currentColor;opacity:1;animation:_dots-pulse_g1823_1 var(--dots-speed) var(--dots-ease) infinite backwards;animation-delay:calc(var(--dots-step, 0) * var(--dots-speed) / 4)}._dot_g1823_31:nth-child(1){--dots-step: 0}._dot_g1823_31:nth-child(2),._dot_g1823_31:nth-child(4){--dots-step: 1}._dot_g1823_31:nth-child(3),._dot_g1823_31:nth-child(5),._dot_g1823_31:nth-child(7){--dots-step: 2}._dot_g1823_31:nth-child(6),._dot_g1823_31:nth-child(8){--dots-step: 3}._dot_g1823_31:nth-child(9){--dots-step: 4}@keyframes _dots-pulse_g1823_1{0%,to{opacity:.2;transform:scale(.7)}50%{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){._dot_g1823_31{animation:none}}:root{--color-neutral-0: #FFFFFF;--color-neutral-50: #F7F7F8;--color-neutral-100: #EFEFF1;--color-neutral-200: #E5E5EA;--color-neutral-300: #D9D9D9;--color-neutral-400: #C1C1C2;--color-neutral-500: #8E8E93;--color-neutral-600: #6B6B6B;--color-neutral-700: #525252;--color-neutral-800: #3A3A3C;--color-neutral-900: #292929;--color-neutral-950: #1D1D1B;--color-neutral-1000: #000000;--color-orange-50: #FDF3EE;--color-orange-100: #FBE2D5;--color-orange-200: #F7C3A8;--color-orange-300: #F0A173;--color-orange-400: #EB7147;--color-orange-500: #E9521E;--color-orange-600: #C2410C;--color-orange-700: #9A3412;--color-sand-100: #FBF3E4;--color-sand-300: #F3D6AC;--color-sand-600: #8A6510;--color-green-100: #DDF0E4;--color-green-600: #157F3D;--color-crimson-100: #F7DEE1;--color-crimson-600: #A3182B;--color-blue-100: #DEE6FA;--color-blue-600: #2A5BD7;--color-background: var(--color-neutral-50);--color-surface: var(--color-neutral-0);--color-surface-muted: var(--color-neutral-100);--color-border: var(--color-neutral-200);--color-border-strong: var(--color-neutral-300);--color-foreground: var(--color-neutral-950);--color-foreground-secondary: var(--color-neutral-700);--color-foreground-muted: var(--color-neutral-600);--color-foreground-disabled: var(--color-neutral-400);--color-primary: var(--color-orange-500);--color-primary-hover: var(--color-orange-600);--color-primary-foreground: var(--color-neutral-0);--color-primary-subtle: var(--color-orange-50);--color-primary-border: var(--color-orange-200);--color-success: var(--color-green-600);--color-success-subtle: var(--color-green-100);--color-warning: var(--color-sand-600);--color-warning-subtle: var(--color-sand-300);--color-danger: var(--color-crimson-600);--color-danger-subtle: var(--color-crimson-100);--color-info: var(--color-blue-600);--color-info-subtle: var(--color-blue-100);--color-grant: var(--color-sand-600);--color-purchased: var(--color-neutral-950);--shadow-overlay-color: rgb(29 29 27 / 20%);--font-display: var(--boost33-font-display, Outfit), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-sans: var(--boost33-font-sans, Inter), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-mono: var(--boost33-font-mono, "Geist Mono"), ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--text-3xs: 9px;--text-2xs: 11px;--text-xs: 12px;--text-sm: 13px;--text-base: 15px;--text-md: 16px;--text-lg: 18px;--text-xl: 20px;--text-2xl: 24px;--text-3xl: 30px;--text-4xl: 36px;--text-5xl: 46px;--text-6xl: 60px;--text-7xl: 78px;--text-nav-label: 14px;--font-weight-light: 300;--font-weight-regular: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--tracking-tighter: -.03em;--tracking-tight: -.02em;--tracking-normal: 0em;--tracking-wide: .04em;--tracking-wider: .09em;--tracking-caps: .05em;--leading-none: 100%;--leading-tight: 120%;--leading-snug: 135%;--leading-normal: 150%;--leading-relaxed: 170%;--breakpoint-mobile: 390px;--breakpoint-desktop: 1440px;--container-sidebar: 264px;--container-sidebar-rail: 56px;--container-command-palette: 560px;--container-content: 1440px;--container-account-menu: 312px;--container-notification-panel: 360px;--spacing-1: 4px;--spacing-2: 8px;--spacing-3: 12px;--spacing-4: 16px;--spacing-4_5: 18px;--spacing-5: 20px;--spacing-6: 24px;--spacing-7: 28px;--spacing-8: 32px;--spacing-10: 40px;--spacing-11: 44px;--spacing-12: 48px;--spacing-16: 64px;--spacing-20: 80px;--spacing-2_5: 10px;--spacing-5_5: 22px;--spacing-1_5: 6px;--spacing-1_25: 5px;--spacing-0_5: 2px;--spacing-2_25: 9px;--spacing-3_5: 14px;--spacing-0_25: 1px;--spacing-topup-reserve: 68px;--spacing-wallet-segment-min: 3px;--spacing-9_5: 38px;--radius-none: 0px;--radius-xs: 2px;--radius-sm: 3px;--radius-md: 4px;--radius-lg: 6px;--radius-xl: 8px;--radius-2xl: 12px;--radius-full: 9999px;--radius-product-tile: 25%}:root{--dur-instant: 80ms;--dur-fast: .15s;--dur-base: .22s;--dur-slow: .32s;--dur-bold: .7s;--dur-hero: .9s;--dur-spin: .7s;--dur-pulse: 1.6s;--ease-out: cubic-bezier(.22, 1, .36, 1);--ease-in: cubic-bezier(.4, 0, 1, 1);--ease-spring: cubic-bezier(.34, 1.56, .64, 1);--lift-sm: -1px;--lift-md: -2px;--rise: 8px;--stagger: 40ms;--duration-fast: var(--dur-fast);--easing-standard: var(--ease-out);--dur-dots: 1s;--ease-in-out-quint: cubic-bezier(.83, 0, .17, 1);--dur-drift: 5s}._root_1xhf4_6{position:fixed;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;padding:var(--spacing-4);overflow:hidden;background-color:var(--launch-ground);color:var(--color-neutral-0);--launch-accent: var(--launch-accent-input, var(--color-neutral-0));isolation:isolate}._mesh_1xhf4_8{position:absolute;top:-12%;right:-12%;bottom:-12%;left:-12%;z-index:0;overflow:hidden;background-color:var(--launch-ground);filter:blur(5.5vmax);animation:_launch-drift_1xhf4_1 var(--dur-drift) ease-in-out 1 both}._shape_1xhf4_81{position:absolute}@keyframes _launch-drift_1xhf4_1{0%,to{transform:none}50%{transform:translate(-1.5%,1%) scale(1.03) rotate(-1deg)}}._backdrop_1xhf4_90{position:absolute;top:0;right:0;bottom:0;left:0;z-index:0;overflow:hidden}._content_1xhf4_13{position:relative;display:flex;flex-direction:column;align-items:center;gap:var(--spacing-5);inline-size:min(280px,100%)}._dots_1xhf4_127{--dots-size: var(--spacing-6);color:var(--launch-accent);mix-blend-mode:soft-light;opacity:1}._bar_1xhf4_160{position:relative;inline-size:100%;block-size:var(--spacing-1);overflow:hidden;border-radius:var(--radius-full)}._track_1xhf4_168{position:absolute;top:0;right:0;bottom:0;left:0;background:color-mix(in srgb,var(--launch-accent) 35%,transparent);mix-blend-mode:soft-light;opacity:.75}._fill_1xhf4_176{position:absolute;inset-block:0;inset-inline-start:0;inline-size:calc(var(--launch-progress, 0) * 1%);border-radius:inherit;background:var(--color-neutral-0);transition:inline-size var(--dur-fast) var(--ease-out)}._bar_1xhf4_160[data-indeterminate=true] ._fill_1xhf4_176{inline-size:33.333%;animation:_launch-indeterminate_1xhf4_1 calc(var(--dur-dots) * 1.5) var(--ease-out) infinite}@keyframes _launch-indeterminate_1xhf4_1{0%{inset-inline-start:-33.333%}to{inset-inline-start:100%}}._caption_1xhf4_202{margin:0;opacity:.8;font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-weight-medium);line-height:var(--leading-normal);text-align:center}@media(prefers-reduced-motion:reduce){._mesh_1xhf4_8{animation:none}._fill_1xhf4_176{transition:none}._bar_1xhf4_160[data-indeterminate=true] ._fill_1xhf4_176{inset-inline-start:33.333%;animation:none}}@media(prefers-contrast){._root_1xhf4_6{background-color:var(--launch-solid);--launch-accent: var(--color-neutral-0)}._mesh_1xhf4_8,._backdrop_1xhf4_90{display:none}._dots_1xhf4_127,._track_1xhf4_168{mix-blend-mode:normal;opacity:1}}
1
+ .btn-primary,.btn-quiet,.btn-danger{cursor:pointer;transition:background-color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),transform var(--dur-instant) var(--ease-out)}.btn-primary{border:none;background:var(--color-primary);color:var(--color-primary-foreground)}.btn-primary:hover:not(:disabled){background:var(--color-primary-hover)}.btn-quiet{background:transparent;color:var(--color-foreground-secondary)}.btn-quiet:hover:not(:disabled){background:var(--color-surface-muted)}.btn-danger{border:1px solid var(--color-danger);background:var(--color-danger);color:var(--color-neutral-0)}.btn-danger:hover:not(:disabled){border-color:color-mix(in srgb,var(--color-danger) 85%,var(--color-neutral-950));background:color-mix(in srgb,var(--color-danger) 85%,var(--color-neutral-950))}.btn-primary:disabled,.btn-quiet:disabled,.btn-danger:disabled{opacity:.55;cursor:not-allowed}.spinner{box-sizing:border-box;width:var(--spacing-4_5);height:var(--spacing-4_5);border:2px solid var(--color-neutral-0);border-right-color:transparent;border-radius:var(--radius-full);animation:boost33-spin var(--dur-spin) linear infinite}.spinner--sm{width:var(--spacing-3_5);height:var(--spacing-3_5)}.spinner--primary{border-color:var(--color-primary);border-right-color:transparent}@keyframes boost33-spin{to{transform:rotate(360deg)}}.sk{display:block;border-radius:var(--radius-md);background:var(--color-surface-muted);animation:boost33-pulse var(--dur-pulse) ease-in-out infinite}.sk-group{animation:boost33-appear var(--dur-base) var(--ease-out) var(--dur-fast) both}.reveal{animation:boost33-appear var(--dur-base) var(--ease-out) both}@keyframes boost33-pulse{50%{opacity:.55}}@keyframes boost33-appear{0%{opacity:0}}@media(prefers-reduced-motion:no-preference){.btn-primary:active:not(:disabled),.btn-quiet:active:not(:disabled),.btn-danger:active:not(:disabled){transform:scale(.98)}}@media(prefers-reduced-motion:reduce){.sk,.sk-group,.reveal,.spinner{animation:none}*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:0s!important;scroll-behavior:auto!important}}._sidebar_17kel_7{display:flex;flex-direction:column;box-sizing:border-box;width:var(--container-sidebar);height:100%;padding-inline:var(--spacing-3);border-right:1px solid var(--color-border);background:var(--color-background);font-family:var(--font-sans)}._sidebar_17kel_7[data-collapsed=true]{width:var(--container-sidebar-rail)}._sidebar_17kel_7>nav{flex-shrink:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;margin:calc(-1 * var(--spacing-1));padding:var(--spacing-1);scroll-padding:var(--spacing-1)}@media(prefers-reduced-motion:reduce){._sidebar_17kel_7>nav{scroll-behavior:auto}}._section_3sxsg_5{display:flex;flex-direction:column}._header_3sxsg_13{margin:0;padding:var(--spacing-2) var(--spacing-2_5);color:var(--color-foreground-muted);font-family:var(--font-sans);font-size:var(--text-2xs);font-weight:var(--font-weight-semibold);letter-spacing:var(--tracking-caps);text-transform:uppercase}._wordmark_1k88r_4{display:flex;align-items:center;gap:var(--spacing-2_5);font-family:var(--font-display)}._mark_1k88r_17{display:inline-flex;flex:0 0 var(--spacing-6);align-items:center;justify-content:center;width:var(--spacing-6);height:var(--spacing-6)}._mark_1k88r_17 svg{width:100%;height:100%}._name_1k88r_35{color:var(--color-foreground);font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--font-weight-semibold);letter-spacing:var(--tracking-tight)}._wordmark_1k88r_4[data-collapsed=true] ._name_1k88r_35{position:absolute;overflow:hidden;clip-path:inset(50%);width:1px;height:1px;white-space:nowrap}._wordmark_1k88r_4[data-collapsed=true]{justify-content:center}._tile_5vhrh_12{fill:var(--color-neutral-950)}._ring_5vhrh_16{fill:var(--color-primary)}._mark_5vhrh_24{display:block}._mark_1jt5g_6{display:block}._ground_1jt5g_17{rx:var(--radius-product-tile)}._row_w21mf_4{display:flex;align-items:center;width:100%;gap:var(--spacing-2_5);padding:var(--spacing-2) var(--spacing-2_5);border:none;border-radius:var(--radius-lg);background:transparent;font-family:var(--font-sans);text-align:left;text-decoration:none;cursor:pointer;transition:background-color var(--dur-fast) var(--ease-out)}._row_w21mf_4:hover{background:var(--color-surface-muted)}._row_w21mf_4[data-active=true]{background:var(--color-surface)}._row_w21mf_4:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}._icon_w21mf_41{display:inline-flex;flex:0 0 var(--spacing-4);align-items:center;justify-content:center;width:var(--spacing-4);height:var(--spacing-4);color:var(--color-foreground-secondary)}._icon_w21mf_41 svg{width:100%;height:100%}._row_w21mf_4[data-active=true] ._icon_w21mf_41{color:var(--color-foreground)}._row_w21mf_4[data-collapsed=true]{justify-content:center}._label_w21mf_66{flex:1 1 auto;min-width:0;overflow:hidden;color:var(--color-foreground-secondary);font-size:var(--text-nav-label);font-weight:var(--font-weight-regular);text-overflow:ellipsis;white-space:nowrap}._row_w21mf_4[data-active=true] ._label_w21mf_66{color:var(--color-foreground);font-weight:var(--font-weight-semibold)}._row_w21mf_4[data-collapsed=true] ._label_w21mf_66{position:absolute;overflow:hidden;clip-path:inset(50%);width:1px;height:1px;white-space:nowrap}._trailingSlot_w21mf_92{display:flex;flex:0 0 var(--spacing-5_5);align-items:center;justify-content:center;width:var(--spacing-5_5);font-family:var(--font-sans);font-size:var(--text-nav-label)}._row_w21mf_4[data-collapsed=true] ._trailingSlot_w21mf_92{display:none}._count_w21mf_106{color:var(--color-foreground-muted)}._countUrgent_w21mf_110{color:var(--color-primary)}@media(prefers-reduced-motion:reduce){._row_w21mf_4{transition:none}}._chip_xxga2_37{--chip-lift: 0px;position:relative;box-sizing:border-box;width:100%;padding:calc(var(--spacing-3) + var(--chip-lift));border:1px solid var(--color-border);border-radius:var(--radius-2xl);background:transparent;font-family:var(--font-sans)}._chip_xxga2_37:not([data-unknown]):hover,._chip_xxga2_37:not([data-unknown]):focus-within,._chip_xxga2_37[data-threshold]{--chip-lift: var(--spacing-0_5);box-shadow:var(--shadow-overlay)}._chip_xxga2_37:not([data-threshold]):not([data-unknown]):hover,._chip_xxga2_37:not([data-threshold]):not([data-unknown]):focus-within{background:var(--color-surface)}._chip_xxga2_37:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}._header_xxga2_74{display:flex;align-items:center;gap:var(--spacing-2)}._chip_xxga2_37:not([data-threshold]):not([data-unknown]) ._header_xxga2_74{padding-right:var(--spacing-topup-reserve)}._name_xxga2_83{min-width:0;overflow:hidden;color:var(--color-foreground-muted);font-size:var(--text-xs);font-weight:var(--font-weight-medium);line-height:var(--leading-tight);text-overflow:ellipsis;white-space:nowrap}._pill_xxga2_162{padding:var(--spacing-0_5) var(--spacing-2);border-radius:var(--radius-full);background:var(--color-warning-subtle);color:var(--color-warning);font-size:var(--text-2xs);font-weight:var(--font-weight-semibold)}._figure_xxga2_171{display:flex;align-items:baseline;gap:var(--spacing-1_5);margin-top:calc(var(--spacing-2_5) + var(--chip-lift))}._amount_xxga2_186{color:var(--color-foreground);font-family:var(--font-mono);font-size:var(--text-2xl);font-weight:var(--font-weight-bold);letter-spacing:var(--tracking-tight);line-height:var(--leading-none)}._unit_xxga2_195{color:var(--color-foreground-muted);font-size:var(--text-xs)}._retry_xxga2_200{width:var(--spacing-3);height:var(--spacing-3);color:var(--color-foreground-muted)}._bar_xxga2_209{display:flex;overflow:hidden;width:100%;height:calc(var(--spacing-1_25) + var(--chip-lift));margin-top:calc(var(--spacing-2_5) + var(--chip-lift));border-radius:var(--radius-full)}._bar_xxga2_209[data-tone=rest]{background:var(--color-surface-muted)}._bar_xxga2_209[data-tone=threshold]{background:var(--color-warning-subtle)}._bar_xxga2_209[data-tone=unknown]{background:var(--color-surface-muted)}._segmentGranted_xxga2_230,._segmentPurchased_xxga2_231{height:100%;transition:width var(--dur-fast) var(--ease-out)}._segmentGranted_xxga2_230{background:var(--color-grant)}._segmentPurchased_xxga2_231{background:var(--color-purchased)}._details_xxga2_275{display:none}._chip_xxga2_37:hover ._details_xxga2_275,._chip_xxga2_37:focus-within ._details_xxga2_275{display:block}._split_xxga2_284{display:flex;flex-direction:column;gap:var(--spacing-1);margin:var(--spacing-2_5) 0 0}._splitRow_xxga2_291{display:flex;align-items:center;justify-content:space-between}._splitLabel_xxga2_297{display:flex;align-items:center;gap:var(--spacing-1_5);color:var(--color-foreground);font-size:var(--text-xs)}._splitAmount_xxga2_305{margin:0;color:var(--color-foreground);font-family:var(--font-mono);font-size:var(--text-xs);font-variant-numeric:tabular-nums}._dotGranted_xxga2_313,._dotPurchased_xxga2_314{width:var(--spacing-1_5);height:var(--spacing-1_5);border-radius:var(--radius-full)}._dotGranted_xxga2_313{background:var(--color-grant)}._dotPurchased_xxga2_314{background:var(--color-purchased)}._footer_xxga2_328{margin:var(--spacing-3) 0 0;padding-top:var(--spacing-1);border-top:1px solid var(--color-border);color:var(--color-foreground-muted);font-size:var(--text-2xs)}._burnNote_xxga2_336{margin:var(--spacing-2_5) 0 0;color:var(--color-foreground-secondary);font-size:var(--text-2xs);line-height:var(--leading-snug)}._topUp_xxga2_87{position:absolute;top:calc(var(--spacing-3) + var(--chip-lift));right:calc(var(--spacing-3) + var(--chip-lift));padding:0;border:none;background:transparent;color:var(--color-primary);font-family:var(--font-sans);font-size:var(--text-xs);font-weight:var(--font-weight-semibold);opacity:0;cursor:pointer;transition:opacity var(--dur-fast) var(--ease-out)}._chip_xxga2_37:hover ._topUp_xxga2_87,._chip_xxga2_37:focus-within ._topUp_xxga2_87,._topUp_xxga2_87:focus-visible{opacity:1}._topUp_xxga2_87:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}._topUp_xxga2_87[data-grown=true]{position:static;width:100%;margin-top:var(--spacing-2_5);padding:var(--spacing-2);border-radius:var(--radius-lg);background:var(--color-primary);color:var(--color-primary-foreground);font-size:var(--text-sm);opacity:1}._topUp_xxga2_87[data-grown=true]:hover{background:var(--color-primary-hover)}._rail_xxga2_402{--chip-lift: 0px;position:relative;display:flex;box-sizing:border-box;width:100%;flex-direction:column;align-items:center;gap:var(--spacing-2);padding:var(--spacing-2);font-family:var(--font-sans)}._railIcon_xxga2_416{width:var(--spacing-6);height:var(--spacing-6);color:var(--color-foreground-secondary)}._railFigure_xxga2_422{color:var(--color-foreground);font-family:var(--font-mono);font-size:var(--text-sm);font-weight:var(--font-weight-semibold);font-variant-numeric:tabular-nums}._rail_xxga2_402 ._bar_xxga2_209{height:var(--spacing-0_5);margin-top:0}._srOnly_xxga2_435{position:absolute;overflow:hidden;clip-path:inset(50%);width:1px;height:1px;white-space:nowrap}@media(prefers-reduced-motion:reduce){._segmentGranted_xxga2_230,._segmentPurchased_xxga2_231,._topUp_xxga2_87{transition:none}}._bar_194bx_7{display:flex;align-items:center;justify-content:space-between;gap:var(--spacing-4);box-sizing:border-box;height:var(--spacing-12);padding:0 var(--spacing-8);border-bottom:1px solid var(--color-border);background:var(--color-surface);font-family:var(--font-sans)}._breadcrumb_194bx_20{display:flex;min-width:0;align-items:center;gap:var(--spacing-2);overflow:hidden;color:var(--color-foreground);font-size:var(--text-sm);font-weight:var(--font-weight-medium);text-overflow:ellipsis;white-space:nowrap}._actions_194bx_33{display:flex;flex:0 0 auto;align-items:center;gap:var(--spacing-2)}@supports (animation-timeline: --a) and (timeline-scope: --a){@container style(--boost33-shell-timeline: on){._bar_194bx_7{position:relative;z-index:1;animation:_scrolled_194bx_1 linear both;animation-timeline:--boost33-shell-scroll;animation-range:0 var(--spacing-10)}}}@keyframes _scrolled_194bx_1{to{box-shadow:var(--shadow-scrolled)}}._header_i17td_42{display:flex;align-items:center;justify-content:space-between;gap:var(--spacing-8);padding:var(--spacing-4_5) var(--spacing-8) var(--spacing-4);background:var(--color-surface);font-family:var(--font-sans)}._headings_i17td_52{display:flex;min-width:0;flex-direction:column;gap:var(--spacing-1)}._title_i17td_33{margin:0;color:var(--color-foreground);font-family:var(--font-display);font-size:var(--text-2xl);font-weight:var(--font-weight-semibold);letter-spacing:var(--tracking-tight);line-height:var(--leading-tight)}._subtitle_i17td_74{margin:0;color:var(--color-foreground-secondary);font-size:var(--text-base);font-weight:var(--font-weight-regular);line-height:var(--leading-snug)}._actions_i17td_82{display:flex;flex:0 0 auto;align-items:center;gap:var(--spacing-2)}._shell_10chf_10{display:flex;height:100%;background:var(--color-surface);font-family:var(--font-sans)}._wordmark_10chf_20{padding:var(--spacing-3) var(--spacing-2_5) var(--spacing-5)}._switcher_10chf_26{padding-bottom:var(--spacing-4)}._foot_10chf_33{display:flex;flex-direction:column;gap:var(--spacing-4);margin-block-start:auto;padding-block-start:var(--spacing-4)}._nav_10chf_45{display:flex;flex-direction:column;gap:var(--spacing-4)}._main_10chf_54{display:flex;min-width:0;flex:1;flex-direction:column}._content_10chf_75{flex:1;min-height:0;overflow-y:auto;background:var(--color-surface)}@supports (animation-timeline: --a) and (timeline-scope: --a){._main_10chf_54{timeline-scope:--boost33-shell-scroll;--boost33-shell-timeline: on}._content_10chf_75{scroll-timeline:--boost33-shell-scroll block}}:root{--shadow-overlay: 0px 16px 40px -10px var(--shadow-overlay-color);--shadow-lift: 0px 10px 24px -14px color-mix(in srgb, var(--color-neutral-950) 28%, transparent);--shadow-scrolled: 0px 6px 16px -12px color-mix(in srgb, var(--color-neutral-950) 35%, transparent)}._root_15f7d_8{position:relative;font-family:var(--font-sans)}._trigger_15f7d_17{display:flex;box-sizing:border-box;width:100%;align-items:center;gap:var(--spacing-2);padding:var(--spacing-2_25) var(--spacing-2);border:1px solid var(--color-border-strong);border-radius:var(--radius-lg);background:transparent;font-family:var(--font-sans);cursor:pointer}._trigger_15f7d_17[aria-expanded=true]{background:var(--color-surface-muted)}._trigger_15f7d_17:focus-visible,._railTrigger_15f7d_46:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}._triggerName_15f7d_56{overflow:hidden;flex:1;color:var(--color-foreground);font-size:var(--text-nav-label);font-weight:var(--font-weight-semibold);text-align:left;text-overflow:ellipsis;white-space:nowrap}._chevron_15f7d_67{width:var(--spacing-3);height:var(--spacing-3);flex-shrink:0;color:var(--color-foreground-muted);transition:transform var(--dur-fast) var(--ease-out)}._trigger_15f7d_17[aria-expanded=true] ._chevron_15f7d_67{transform:rotate(180deg)}._railTrigger_15f7d_46{display:flex;box-sizing:border-box;width:100%;min-height:var(--spacing-6);align-items:flex-start;justify-content:center;padding:0;border:none;background:transparent;cursor:pointer}._panel_15f7d_109{position:absolute;z-index:1;top:100%;left:0;width:var(--container-sidebar);box-sizing:border-box;margin-top:var(--spacing-0_5);padding:var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--radius-2xl);background:var(--color-surface);box-shadow:var(--shadow-overlay)}._hubRow_15f7d_135,._productRow_15f7d_136,._accountRow_15f7d_137{display:flex;box-sizing:border-box;width:100%;align-items:center;gap:var(--spacing-2_5);padding:var(--spacing-2);border:none;border-radius:var(--radius-lg);background:transparent;color:var(--color-foreground);font-family:var(--font-sans);text-align:left;text-decoration:none;cursor:pointer}._hubRow_15f7d_135:hover,._productRow_15f7d_136:hover,._accountRow_15f7d_137:hover{background:var(--color-surface-muted)}._hubRow_15f7d_135:focus-visible,._productRow_15f7d_136:focus-visible,._accountRow_15f7d_137:focus-visible{outline:2px solid var(--color-primary);outline-offset:-2px}._products_15f7d_144{display:flex;flex-direction:column;gap:var(--spacing-0_5);margin:0;padding:0;list-style:none}._productRow_15f7d_136[data-current=true]{background:var(--color-surface-muted)}._productRow_15f7d_136[data-entitled=false] ._rowName_15f7d_193{color:var(--color-foreground-muted)}._accountRow_15f7d_137{padding-inline:var(--spacing-3)}._accountRow_15f7d_137 ._rowName_15f7d_193{font-size:var(--text-sm)}._accountRow_15f7d_137 ._rowSub_15f7d_213{font-size:var(--text-2xs)}._accountRow_15f7d_137[data-actionable=false]{cursor:default}._accountRow_15f7d_137[data-actionable=false]:hover{background:transparent}._rowText_15f7d_238{display:flex;min-width:0;flex-direction:column}._hubRow_15f7d_135 ._rowText_15f7d_238{gap:var(--spacing-0_5)}._rowName_15f7d_193{overflow:hidden;color:var(--color-foreground);font-size:var(--text-nav-label);font-weight:var(--font-weight-regular);text-overflow:ellipsis;white-space:nowrap}._productRow_15f7d_136 ._rowName_15f7d_193{flex:1}._rowSub_15f7d_213{overflow:hidden;color:var(--color-foreground-muted);font-size:var(--text-xs);text-overflow:ellipsis;white-space:nowrap}._hubMark_15f7d_281{width:var(--spacing-5);height:var(--spacing-5);flex-shrink:0;color:var(--color-foreground)}._tag_15f7d_297{flex-shrink:0;margin-left:auto;padding:var(--spacing-0_5) var(--spacing-1_5);border-radius:var(--radius-full);background:var(--color-surface-muted);color:var(--color-foreground-muted);font-size:var(--text-2xs);font-weight:var(--font-weight-medium)}._check_15f7d_308{width:var(--spacing-4);height:var(--spacing-4);flex-shrink:0;margin-left:auto;color:var(--color-foreground)}._avatar_15f7d_321{display:grid;width:var(--spacing-6);height:var(--spacing-6);flex-shrink:0;border-radius:var(--radius-lg);background:var(--color-surface-muted);color:var(--color-foreground-secondary);font-size:var(--text-3xs);font-weight:var(--font-weight-semibold);place-items:center}._chevronRight_15f7d_334{width:var(--spacing-4);height:var(--spacing-4);flex-shrink:0;margin-left:auto;color:var(--color-foreground-muted)}._divider_15f7d_355{margin:var(--spacing-2_25) 0 var(--spacing-2);border:none;border-top:1px solid var(--color-border)}._products_15f7d_144+._divider_15f7d_355{margin:var(--spacing-1_5) 0 var(--spacing-1)}@media(prefers-reduced-motion:reduce){._chevron_15f7d_67{transition:none}}._root_g1823_11{--dots-size: var(--spacing-8);--dots-speed: var(--dur-dots);--dots-ease: var(--ease-in-out-quint);--dots-gap: calc(var(--dots-size) * .14);--dots-dot: calc((var(--dots-size) - var(--dots-gap) * 2) / 3);display:inline-flex;align-items:center;justify-content:center}._grid_g1823_25{display:grid;gap:var(--dots-gap);grid-template-columns:repeat(3,var(--dots-dot))}._dot_g1823_31{width:var(--dots-dot);height:var(--dots-dot);border-radius:var(--radius-full);background:currentColor;opacity:1;animation:_dots-pulse_g1823_1 var(--dots-speed) var(--dots-ease) infinite backwards;animation-delay:calc(var(--dots-step, 0) * var(--dots-speed) / 4)}._dot_g1823_31:nth-child(1){--dots-step: 0}._dot_g1823_31:nth-child(2),._dot_g1823_31:nth-child(4){--dots-step: 1}._dot_g1823_31:nth-child(3),._dot_g1823_31:nth-child(5),._dot_g1823_31:nth-child(7){--dots-step: 2}._dot_g1823_31:nth-child(6),._dot_g1823_31:nth-child(8){--dots-step: 3}._dot_g1823_31:nth-child(9){--dots-step: 4}@keyframes _dots-pulse_g1823_1{0%,to{opacity:.2;transform:scale(.7)}50%{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){._dot_g1823_31{animation:none}}:root{--color-neutral-0: #FFFFFF;--color-neutral-50: #F7F7F8;--color-neutral-100: #EFEFF1;--color-neutral-200: #E5E5EA;--color-neutral-300: #D9D9D9;--color-neutral-400: #C1C1C2;--color-neutral-500: #8E8E93;--color-neutral-600: #6B6B6B;--color-neutral-700: #525252;--color-neutral-800: #3A3A3C;--color-neutral-900: #292929;--color-neutral-950: #1D1D1B;--color-neutral-1000: #000000;--color-orange-50: #FDF3EE;--color-orange-100: #FBE2D5;--color-orange-200: #F7C3A8;--color-orange-300: #F0A173;--color-orange-400: #EB7147;--color-orange-500: #E9521E;--color-orange-600: #C2410C;--color-orange-700: #9A3412;--color-sand-100: #FBF3E4;--color-sand-300: #F3D6AC;--color-sand-600: #8A6510;--color-green-100: #DDF0E4;--color-green-600: #157F3D;--color-crimson-100: #F7DEE1;--color-crimson-600: #A3182B;--color-blue-100: #DEE6FA;--color-blue-600: #2A5BD7;--color-background: var(--color-neutral-50);--color-surface: var(--color-neutral-0);--color-surface-muted: var(--color-neutral-100);--color-border: var(--color-neutral-200);--color-border-strong: var(--color-neutral-300);--color-foreground: var(--color-neutral-950);--color-foreground-secondary: var(--color-neutral-700);--color-foreground-muted: var(--color-neutral-600);--color-foreground-disabled: var(--color-neutral-400);--color-primary: var(--color-orange-500);--color-primary-hover: var(--color-orange-600);--color-primary-foreground: var(--color-neutral-0);--color-primary-subtle: var(--color-orange-50);--color-primary-border: var(--color-orange-200);--color-success: var(--color-green-600);--color-success-subtle: var(--color-green-100);--color-warning: var(--color-sand-600);--color-warning-subtle: var(--color-sand-300);--color-danger: var(--color-crimson-600);--color-danger-subtle: var(--color-crimson-100);--color-info: var(--color-blue-600);--color-info-subtle: var(--color-blue-100);--color-grant: var(--color-sand-600);--color-purchased: var(--color-neutral-950);--shadow-overlay-color: rgb(29 29 27 / 20%);--font-display: var(--boost33-font-display, Outfit), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-sans: var(--boost33-font-sans, Inter), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-mono: var(--boost33-font-mono, "Geist Mono"), ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--text-3xs: 9px;--text-2xs: 11px;--text-xs: 12px;--text-sm: 13px;--text-base: 15px;--text-md: 16px;--text-lg: 18px;--text-xl: 20px;--text-2xl: 24px;--text-3xl: 30px;--text-4xl: 36px;--text-5xl: 46px;--text-6xl: 60px;--text-7xl: 78px;--text-nav-label: 14px;--font-weight-light: 300;--font-weight-regular: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--tracking-tighter: -.03em;--tracking-tight: -.02em;--tracking-normal: 0em;--tracking-wide: .04em;--tracking-wider: .09em;--tracking-caps: .05em;--leading-none: 100%;--leading-tight: 120%;--leading-snug: 135%;--leading-normal: 150%;--leading-relaxed: 170%;--breakpoint-mobile: 390px;--breakpoint-desktop: 1440px;--container-sidebar: 264px;--container-sidebar-rail: 56px;--container-command-palette: 560px;--container-content: 1440px;--container-account-menu: 312px;--container-notification-panel: 360px;--spacing-1: 4px;--spacing-2: 8px;--spacing-3: 12px;--spacing-4: 16px;--spacing-4_5: 18px;--spacing-5: 20px;--spacing-6: 24px;--spacing-7: 28px;--spacing-8: 32px;--spacing-10: 40px;--spacing-11: 44px;--spacing-12: 48px;--spacing-16: 64px;--spacing-20: 80px;--spacing-2_5: 10px;--spacing-5_5: 22px;--spacing-1_5: 6px;--spacing-1_25: 5px;--spacing-0_5: 2px;--spacing-2_25: 9px;--spacing-3_5: 14px;--spacing-0_25: 1px;--spacing-topup-reserve: 68px;--spacing-wallet-segment-min: 3px;--spacing-9_5: 38px;--radius-none: 0px;--radius-xs: 2px;--radius-sm: 3px;--radius-md: 4px;--radius-lg: 6px;--radius-xl: 8px;--radius-2xl: 12px;--radius-full: 9999px;--radius-product-tile: 25%}:root{--dur-instant: 80ms;--dur-fast: .15s;--dur-base: .22s;--dur-slow: .32s;--dur-bold: .7s;--dur-hero: .9s;--dur-spin: .7s;--dur-pulse: 1.6s;--ease-out: cubic-bezier(.22, 1, .36, 1);--ease-in: cubic-bezier(.4, 0, 1, 1);--ease-spring: cubic-bezier(.34, 1.56, .64, 1);--lift-sm: -1px;--lift-md: -2px;--rise: 8px;--stagger: 40ms;--duration-fast: var(--dur-fast);--easing-standard: var(--ease-out);--dur-dots: 1s;--ease-in-out-quint: cubic-bezier(.83, 0, .17, 1)}._root_1pg11_6{position:fixed;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;padding:var(--spacing-4);overflow:hidden;background-color:var(--color-neutral-1000);color:var(--color-neutral-0);--launch-accent: var(--launch-accent-input, var(--color-neutral-0));isolation:isolate}._glow_1pg11_9{position:absolute;top:50%;left:50%;z-index:0;width:298.333%;height:238.222%;transform:translate(-50%);border-radius:50%;background-image:radial-gradient(circle farthest-corner at 50% 50% in oklab,var(--color-orange-500) 0%,var(--color-orange-600) 28%,var(--color-orange-700) 48%,oklab(from var(--color-orange-700) l a b / 0%) 72%);filter:blur(5.5vmax)}._backdrop_1pg11_103{position:absolute;top:0;right:0;bottom:0;left:0;z-index:0;overflow:hidden}._content_1pg11_16{position:relative;display:flex;flex-direction:column;align-items:center;gap:var(--spacing-5);inline-size:min(280px,100%)}._dots_1pg11_139{--dots-size: var(--spacing-6);color:var(--launch-accent);mix-blend-mode:soft-light;opacity:1}._bar_1pg11_178{position:relative;inline-size:100%;block-size:var(--spacing-1);overflow:hidden;border-radius:var(--radius-full)}._track_1pg11_186{position:absolute;top:0;right:0;bottom:0;left:0;background:color-mix(in srgb,var(--launch-accent) 35%,transparent);mix-blend-mode:soft-light;opacity:.75}._fill_1pg11_194{position:absolute;inset-block:0;inset-inline-start:0;inline-size:calc(var(--launch-progress, 0) * 1%);border-radius:inherit;background:var(--color-neutral-0);transition:inline-size var(--dur-fast) var(--ease-out)}._bar_1pg11_178[data-indeterminate=true] ._fill_1pg11_194{inline-size:33.333%;animation:_launch-indeterminate_1pg11_1 calc(var(--dur-dots) * 1.5) var(--ease-out) infinite}@keyframes _launch-indeterminate_1pg11_1{0%{inset-inline-start:-33.333%}to{inset-inline-start:100%}}._caption_1pg11_220{margin:0;opacity:.8;font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-weight-medium);line-height:var(--leading-normal);text-align:center}@media(prefers-reduced-motion:reduce){._fill_1pg11_194{transition:none}._bar_1pg11_178[data-indeterminate=true] ._fill_1pg11_194{inset-inline-start:33.333%;animation:none}}@media(prefers-contrast){._root_1pg11_6{--launch-accent: var(--color-neutral-0)}._glow_1pg11_9,._backdrop_1pg11_103{display:none}._dots_1pg11_139,._track_1pg11_186{mix-blend-mode:normal;opacity:1}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boost33/ui",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "The app shell every Boost33 product renders inside.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",