@boost33/ui 0.2.0 → 0.3.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 +5 -2
- package/dist/anchored-overlay.d.ts +28 -11
- package/dist/anchored-overlay.js +125 -0
- package/dist/anchored-overlay.js.map +1 -0
- package/dist/components/AppShell/AppShell.d.ts +19 -4
- package/dist/components/AppShell/AppShell.js +59 -0
- package/dist/components/AppShell/AppShell.js.map +1 -0
- package/dist/components/AppShell/AppShell.module.css.js +20 -0
- package/dist/components/AppShell/AppShell.module.css.js.map +1 -0
- package/dist/components/AppSwitcher/AppSwitcher.d.ts +96 -0
- package/dist/components/AppSwitcher/AppSwitcher.js +81 -0
- package/dist/components/AppSwitcher/AppSwitcher.js.map +1 -0
- package/dist/components/AppSwitcher/AppSwitcher.module.css.js +44 -0
- package/dist/components/AppSwitcher/AppSwitcher.module.css.js.map +1 -0
- package/dist/components/AppSwitcher/icons.d.ts +20 -0
- package/dist/components/AppSwitcher/icons.js +25 -0
- package/dist/components/AppSwitcher/icons.js.map +1 -0
- package/dist/components/AppSwitcher/labels.d.ts +60 -0
- package/dist/components/AppSwitcher/labels.js +16 -0
- package/dist/components/AppSwitcher/labels.js.map +1 -0
- package/dist/components/Boost33Mark/Boost33Mark.js +62 -0
- package/dist/components/Boost33Mark/Boost33Mark.js.map +1 -0
- package/dist/components/Boost33Mark/Boost33Mark.module.css.js +12 -0
- package/dist/components/Boost33Mark/Boost33Mark.module.css.js.map +1 -0
- package/dist/components/NavItem/NavItem.d.ts +12 -2
- package/dist/components/NavItem/NavItem.js +18 -0
- package/dist/components/NavItem/NavItem.js.map +1 -0
- package/dist/components/NavItem/NavItem.module.css.js +18 -0
- package/dist/components/NavItem/NavItem.module.css.js.map +1 -0
- package/dist/components/NavSection/NavSection.js +14 -0
- package/dist/components/NavSection/NavSection.js.map +1 -0
- package/dist/components/NavSection/NavSection.module.css.js +10 -0
- package/dist/components/NavSection/NavSection.module.css.js.map +1 -0
- package/dist/components/PageHeader/PageHeader.js +15 -0
- package/dist/components/PageHeader/PageHeader.js.map +1 -0
- package/dist/components/PageHeader/PageHeader.module.css.js +16 -0
- package/dist/components/PageHeader/PageHeader.module.css.js.map +1 -0
- package/dist/components/ProductMark/ProductMark.d.ts +15 -0
- package/dist/components/ProductMark/ProductMark.js +73 -0
- package/dist/components/ProductMark/ProductMark.js.map +1 -0
- package/dist/components/ProductMark/ProductMark.module.css.js +10 -0
- package/dist/components/ProductMark/ProductMark.module.css.js.map +1 -0
- package/dist/components/Sidebar/NavHeightBudgetWarning.d.ts +3 -0
- package/dist/components/Sidebar/NavHeightBudgetWarning.js +28 -0
- package/dist/components/Sidebar/NavHeightBudgetWarning.js.map +1 -0
- package/dist/components/Sidebar/Sidebar.js +14 -0
- package/dist/components/Sidebar/Sidebar.js.map +1 -0
- package/dist/components/Sidebar/Sidebar.module.css.js +8 -0
- package/dist/components/Sidebar/Sidebar.module.css.js.map +1 -0
- package/dist/components/TopBar/TopBar.js +12 -0
- package/dist/components/TopBar/TopBar.js.map +1 -0
- package/dist/components/TopBar/TopBar.module.css.js +12 -0
- package/dist/components/TopBar/TopBar.module.css.js.map +1 -0
- package/dist/components/WalletChip/WalletChip.d.ts +34 -1
- package/dist/components/WalletChip/WalletChip.js +68 -0
- package/dist/components/WalletChip/WalletChip.js.map +1 -0
- package/dist/components/WalletChip/WalletChip.module.css.js +56 -0
- package/dist/components/WalletChip/WalletChip.module.css.js.map +1 -0
- package/dist/components/WalletChip/format.d.ts +45 -5
- package/dist/components/WalletChip/format.js +29 -0
- package/dist/components/WalletChip/format.js.map +1 -0
- package/dist/components/WalletChip/icons.js +18 -0
- package/dist/components/WalletChip/icons.js.map +1 -0
- package/dist/components/WalletChip/labels.d.ts +143 -0
- package/dist/components/WalletChip/labels.js +38 -0
- package/dist/components/WalletChip/labels.js.map +1 -0
- package/dist/components/Wordmark/Wordmark.js +12 -0
- package/dist/components/Wordmark/Wordmark.js.map +1 -0
- package/dist/components/Wordmark/Wordmark.module.css.js +12 -0
- package/dist/components/Wordmark/Wordmark.module.css.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +41 -420
- package/dist/index.js.map +1 -1
- package/dist/nav-height-budget.d.ts +51 -13
- package/dist/nav-height-budget.js +38 -0
- package/dist/nav-height-budget.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/theme.css +190 -0
- package/package.json +12 -4
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const c = "_root_chh8a_8", o = "_trigger_chh8a_17", _ = "_railTrigger_chh8a_46", h = "_triggerName_chh8a_56", r = "_chevron_chh8a_67", t = "_panel_chh8a_109", a = "_hubRow_chh8a_135", e = "_productRow_chh8a_136", n = "_accountRow_chh8a_137", s = "_products_chh8a_144", g = "_rowName_chh8a_193", i = "_rowSub_chh8a_213", u = "_rowText_chh8a_217", w = "_hubMark_chh8a_260", d = "_tag_chh8a_269", v = "_check_chh8a_280", R = "_avatar_chh8a_293", p = "_chevronRight_chh8a_306", b = "_divider_chh8a_327", l = {
|
|
2
|
+
root: c,
|
|
3
|
+
trigger: o,
|
|
4
|
+
railTrigger: _,
|
|
5
|
+
triggerName: h,
|
|
6
|
+
chevron: r,
|
|
7
|
+
panel: t,
|
|
8
|
+
hubRow: a,
|
|
9
|
+
productRow: e,
|
|
10
|
+
accountRow: n,
|
|
11
|
+
products: s,
|
|
12
|
+
rowName: g,
|
|
13
|
+
rowSub: i,
|
|
14
|
+
rowText: u,
|
|
15
|
+
hubMark: w,
|
|
16
|
+
tag: d,
|
|
17
|
+
check: v,
|
|
18
|
+
avatar: R,
|
|
19
|
+
chevronRight: p,
|
|
20
|
+
divider: b
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
n as accountRow,
|
|
24
|
+
R as avatar,
|
|
25
|
+
v as check,
|
|
26
|
+
r as chevron,
|
|
27
|
+
p as chevronRight,
|
|
28
|
+
l as default,
|
|
29
|
+
b as divider,
|
|
30
|
+
w as hubMark,
|
|
31
|
+
a as hubRow,
|
|
32
|
+
t as panel,
|
|
33
|
+
e as productRow,
|
|
34
|
+
s as products,
|
|
35
|
+
_ as railTrigger,
|
|
36
|
+
c as root,
|
|
37
|
+
g as rowName,
|
|
38
|
+
i as rowSub,
|
|
39
|
+
u as rowText,
|
|
40
|
+
d as tag,
|
|
41
|
+
o as trigger,
|
|
42
|
+
h as triggerName
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=AppSwitcher.module.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppSwitcher.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 2x2 grid that stands for "all Boost33 products" on the Hub row. Not a
|
|
3
|
+
* ProductMark: the Hub is not a product and takes no dark tile -- it is four
|
|
4
|
+
* rounded squares in the row's own ink, the universal "all apps" glyph.
|
|
5
|
+
*/
|
|
6
|
+
export declare function HubMark({ className }: {
|
|
7
|
+
className?: string;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
9
|
+
/** The chevron on the trigger. Points down when closed; the CSS flips it up when open. */
|
|
10
|
+
export declare function Chevron({ className }: {
|
|
11
|
+
className?: string;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
/** The chevron on the account row, pointing at the second panel it opens. */
|
|
14
|
+
export declare function ChevronRight({ className }: {
|
|
15
|
+
className?: string;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
|
+
/** The check marking the current product -- a check, not a colour (B33-479). */
|
|
18
|
+
export declare function Check({ className }: {
|
|
19
|
+
className?: string;
|
|
20
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as r, jsxs as t } from "react/jsx-runtime";
|
|
2
|
+
function o({ className: e }) {
|
|
3
|
+
return /* @__PURE__ */ t("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
4
|
+
/* @__PURE__ */ r("rect", { x: "3", y: "3", width: "7", height: "7", rx: "2" }),
|
|
5
|
+
/* @__PURE__ */ r("rect", { x: "14", y: "3", width: "7", height: "7", rx: "2" }),
|
|
6
|
+
/* @__PURE__ */ r("rect", { x: "3", y: "14", width: "7", height: "7", rx: "2" }),
|
|
7
|
+
/* @__PURE__ */ r("rect", { x: "14", y: "14", width: "7", height: "7", rx: "2" })
|
|
8
|
+
] });
|
|
9
|
+
}
|
|
10
|
+
function i({ className: e }) {
|
|
11
|
+
return /* @__PURE__ */ r("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ r("path", { d: "M6 9l6 6 6-6" }) });
|
|
12
|
+
}
|
|
13
|
+
function h({ className: e }) {
|
|
14
|
+
return /* @__PURE__ */ r("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ r("path", { d: "M9 6l6 6-6 6" }) });
|
|
15
|
+
}
|
|
16
|
+
function d({ className: e }) {
|
|
17
|
+
return /* @__PURE__ */ r("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ r("path", { d: "M5 12l5 5 9-10" }) });
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
d as Check,
|
|
21
|
+
i as Chevron,
|
|
22
|
+
h as ChevronRight,
|
|
23
|
+
o as HubMark
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.js","sources":["../../../src/components/AppSwitcher/icons.tsx"],"sourcesContent":["// The switcher's own small glyphs, drawn in `currentColor` so the surrounding\n// text colour carries them and the no-hardcoded-hex guard stays satisfied. All\n// decorative -- the row's own text carries meaning -- so every one is\n// aria-hidden. The four product marks are ProductMark's; these are only the\n// chrome ProductMark does not draw.\n\n/**\n * The 2x2 grid that stands for \"all Boost33 products\" on the Hub row. Not a\n * ProductMark: the Hub is not a product and takes no dark tile -- it is four\n * rounded squares in the row's own ink, the universal \"all apps\" glyph.\n */\nexport function HubMark({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"2\" />\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"2\" />\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"2\" />\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"2\" />\n </svg>\n )\n}\n\n/** The chevron on the trigger. Points down when closed; the CSS flips it up when open. */\nexport function Chevron({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n )\n}\n\n/** The chevron on the account row, pointing at the second panel it opens. */\nexport function ChevronRight({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M9 6l6 6-6 6\" />\n </svg>\n )\n}\n\n/** The check marking the current product -- a check, not a colour (B33-479). */\nexport function Check({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M5 12l5 5 9-10\" />\n </svg>\n )\n}\n"],"names":["HubMark","className","jsxs","jsx","Chevron","ChevronRight","Check"],"mappings":";AAWO,SAASA,EAAQ,EAAE,WAAAC,KAAqC;AAC7D,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAAD,GAAsB,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,gBAAe,SAAQ,eAAY,QAClI,UAAA;AAAA,IAAA,gBAAAE,EAAC,QAAA,EAAK,GAAE,KAAI,GAAE,KAAI,OAAM,KAAI,QAAO,KAAI,IAAG,IAAA,CAAI;AAAA,IAC9C,gBAAAA,EAAC,QAAA,EAAK,GAAE,MAAK,GAAE,KAAI,OAAM,KAAI,QAAO,KAAI,IAAG,IAAA,CAAI;AAAA,IAC/C,gBAAAA,EAAC,QAAA,EAAK,GAAE,KAAI,GAAE,MAAK,OAAM,KAAI,QAAO,KAAI,IAAG,IAAA,CAAI;AAAA,IAC/C,gBAAAA,EAAC,QAAA,EAAK,GAAE,MAAK,GAAE,MAAK,OAAM,KAAI,QAAO,KAAI,IAAG,IAAA,CAAI;AAAA,EAAA,GAClD;AAEJ;AAGO,SAASC,EAAQ,EAAE,WAAAH,KAAqC;AAC7D,SACE,gBAAAE,EAAC,SAAI,WAAAF,GAAsB,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,eAAY,QACxJ,UAAA,gBAAAE,EAAC,QAAA,EAAK,GAAE,eAAA,CAAe,EAAA,CACzB;AAEJ;AAGO,SAASE,EAAa,EAAE,WAAAJ,KAAqC;AAClE,SACE,gBAAAE,EAAC,SAAI,WAAAF,GAAsB,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,eAAY,QACxJ,UAAA,gBAAAE,EAAC,QAAA,EAAK,GAAE,eAAA,CAAe,EAAA,CACzB;AAEJ;AAGO,SAASG,EAAM,EAAE,WAAAL,KAAqC;AAC3D,SACE,gBAAAE,EAAC,SAAI,WAAAF,GAAsB,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,OAAM,eAAc,SAAQ,gBAAe,SAAQ,eAAY,QAC1J,UAAA,gBAAAE,EAAC,QAAA,EAAK,GAAE,iBAAA,CAAiB,EAAA,CAC3B;AAEJ;"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Every user-facing string the switcher renders that is not row data. */
|
|
2
|
+
export interface AppSwitcherLabels {
|
|
3
|
+
/**
|
|
4
|
+
* The panel's accessible name. A disclosure panel carries no widget role, so
|
|
5
|
+
* it takes an `aria-label` to be named at all (ADR-0010). Default
|
|
6
|
+
* "Boost33 products".
|
|
7
|
+
*/
|
|
8
|
+
panel: string;
|
|
9
|
+
/**
|
|
10
|
+
* The tag on a product the account is not entitled to. Not a gate -- the row
|
|
11
|
+
* stays an ordinary link -- only a hint (ADR-0010: "Not entitled is not
|
|
12
|
+
* disabled"). Default "Not on plan".
|
|
13
|
+
*/
|
|
14
|
+
notOnPlan: string;
|
|
15
|
+
/**
|
|
16
|
+
* The trigger's name when `currentSlug` matches no product in the supplied
|
|
17
|
+
* list, so there is no product name to put there. Default "Switch product".
|
|
18
|
+
*
|
|
19
|
+
* That case is reachable by design: `AppSwitcherProduct.slug` is typed
|
|
20
|
+
* `string` rather than `ProductSlug` so an unknown slug degrades to a bare
|
|
21
|
+
* tile instead of failing (ADR-0003 -- Identity owns the registry and this
|
|
22
|
+
* package does not know which slugs exist). A fifth Identity product, or a
|
|
23
|
+
* `currentSlug` left stale by a rename, lands there. Before B33-919 the
|
|
24
|
+
* degradation took the button's accessible name with it and the only control
|
|
25
|
+
* in the collapsed shell announced nothing at all.
|
|
26
|
+
*
|
|
27
|
+
* It names the control rather than describing the missing product, because
|
|
28
|
+
* the product is precisely what this package does not know. "Switch product"
|
|
29
|
+
* is true in every state; a guess at the product's name would not be.
|
|
30
|
+
*/
|
|
31
|
+
switchProduct: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The English defaults. A consumer that passes nothing renders exactly what the
|
|
35
|
+
* appswitcher-* baselines were captured showing, so those baselines do not move.
|
|
36
|
+
* `switchProduct` is no exception: it only ever reaches the screen when
|
|
37
|
+
* `currentSlug` matches nothing, and all three baselines were captured with the
|
|
38
|
+
* Wallet current.
|
|
39
|
+
*/
|
|
40
|
+
export declare const defaultAppSwitcherLabels: AppSwitcherLabels;
|
|
41
|
+
/**
|
|
42
|
+
* Merge a consumer's partial `labels` onto the English defaults, treating an
|
|
43
|
+
* explicitly-`undefined` field as unsupplied -- the same resolution
|
|
44
|
+
* `resolveWalletChipLabels` performs, for the same two reasons.
|
|
45
|
+
*
|
|
46
|
+
* The first is forward compatibility, and it is why this exists now. `labels`
|
|
47
|
+
* used to be a whole `AppSwitcherLabels`, so a consumer wrote the object out in
|
|
48
|
+
* full; adding `switchProduct` to a required-field interface would have failed
|
|
49
|
+
* the typecheck of every app that had done so, turning an accessibility fix
|
|
50
|
+
* into a breaking change across four products on a patch bump (CLAUDE.md,
|
|
51
|
+
* "Versioning"). Taking a `Partial` means a consumer supplies the fields it
|
|
52
|
+
* wants to translate and inherits the rest, today and at the next field.
|
|
53
|
+
*
|
|
54
|
+
* The second is that a missed translation key must fall back to English rather
|
|
55
|
+
* than blank the string. A next-intl `t('...')` returns `undefined` on a miss,
|
|
56
|
+
* so `{ panel: undefined }` is what one missing key looks like at the call
|
|
57
|
+
* site. A plain object spread copies that `undefined` across and unnames the
|
|
58
|
+
* panel; a per-field skip does not (B33-873).
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveAppSwitcherLabels(labels?: Partial<AppSwitcherLabels>): AppSwitcherLabels;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const n = {
|
|
2
|
+
panel: "Boost33 products",
|
|
3
|
+
notOnPlan: "Not on plan",
|
|
4
|
+
switchProduct: "Switch product"
|
|
5
|
+
};
|
|
6
|
+
function r(t) {
|
|
7
|
+
const e = Object.fromEntries(
|
|
8
|
+
Object.entries(t ?? {}).filter(([, o]) => o !== void 0)
|
|
9
|
+
);
|
|
10
|
+
return { ...n, ...e };
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
n as defaultAppSwitcherLabels,
|
|
14
|
+
r as resolveAppSwitcherLabels
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=labels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"labels.js","sources":["../../../src/components/AppSwitcher/labels.ts"],"sourcesContent":["// The switcher's own user-facing words, each a prop with an English default --\n// the same pattern WalletChipLabels follows, and for the same reason: the first\n// two consumers are French-default, and the package renders what it is given\n// rather than taking an i18n dependency (CLAUDE.md; B33-849). The product names,\n// the Hub's name and blurb, and the account row's name and subtitle are not here\n// -- they are Identity's data, supplied per row on `products`, `hub` and\n// `account`, not copy this package owns.\n\n/** Every user-facing string the switcher renders that is not row data. */\nexport interface AppSwitcherLabels {\n /**\n * The panel's accessible name. A disclosure panel carries no widget role, so\n * it takes an `aria-label` to be named at all (ADR-0010). Default\n * \"Boost33 products\".\n */\n panel: string\n /**\n * The tag on a product the account is not entitled to. Not a gate -- the row\n * stays an ordinary link -- only a hint (ADR-0010: \"Not entitled is not\n * disabled\"). Default \"Not on plan\".\n */\n notOnPlan: string\n /**\n * The trigger's name when `currentSlug` matches no product in the supplied\n * list, so there is no product name to put there. Default \"Switch product\".\n *\n * That case is reachable by design: `AppSwitcherProduct.slug` is typed\n * `string` rather than `ProductSlug` so an unknown slug degrades to a bare\n * tile instead of failing (ADR-0003 -- Identity owns the registry and this\n * package does not know which slugs exist). A fifth Identity product, or a\n * `currentSlug` left stale by a rename, lands there. Before B33-919 the\n * degradation took the button's accessible name with it and the only control\n * in the collapsed shell announced nothing at all.\n *\n * It names the control rather than describing the missing product, because\n * the product is precisely what this package does not know. \"Switch product\"\n * is true in every state; a guess at the product's name would not be.\n */\n switchProduct: string\n}\n\n/**\n * The English defaults. A consumer that passes nothing renders exactly what the\n * appswitcher-* baselines were captured showing, so those baselines do not move.\n * `switchProduct` is no exception: it only ever reaches the screen when\n * `currentSlug` matches nothing, and all three baselines were captured with the\n * Wallet current.\n */\nexport const defaultAppSwitcherLabels: AppSwitcherLabels = {\n panel: 'Boost33 products',\n notOnPlan: 'Not on plan',\n switchProduct: 'Switch product',\n}\n\n/**\n * Merge a consumer's partial `labels` onto the English defaults, treating an\n * explicitly-`undefined` field as unsupplied -- the same resolution\n * `resolveWalletChipLabels` performs, for the same two reasons.\n *\n * The first is forward compatibility, and it is why this exists now. `labels`\n * used to be a whole `AppSwitcherLabels`, so a consumer wrote the object out in\n * full; adding `switchProduct` to a required-field interface would have failed\n * the typecheck of every app that had done so, turning an accessibility fix\n * into a breaking change across four products on a patch bump (CLAUDE.md,\n * \"Versioning\"). Taking a `Partial` means a consumer supplies the fields it\n * wants to translate and inherits the rest, today and at the next field.\n *\n * The second is that a missed translation key must fall back to English rather\n * than blank the string. A next-intl `t('...')` returns `undefined` on a miss,\n * so `{ panel: undefined }` is what one missing key looks like at the call\n * site. A plain object spread copies that `undefined` across and unnames the\n * panel; a per-field skip does not (B33-873).\n */\nexport function resolveAppSwitcherLabels(labels?: Partial<AppSwitcherLabels>): AppSwitcherLabels {\n const supplied = Object.fromEntries(\n Object.entries(labels ?? {}).filter(([, value]) => value !== undefined),\n ) as Partial<AppSwitcherLabels>\n return { ...defaultAppSwitcherLabels, ...supplied }\n}\n"],"names":["defaultAppSwitcherLabels","resolveAppSwitcherLabels","labels","supplied","value"],"mappings":"AAgDO,MAAMA,IAA8C;AAAA,EACzD,OAAO;AAAA,EACP,WAAW;AAAA,EACX,eAAe;AACjB;AAqBO,SAASC,EAAyBC,GAAwD;AAC/F,QAAMC,IAAW,OAAO;AAAA,IACtB,OAAO,QAAQD,KAAU,EAAE,EAAE,OAAO,CAAC,CAAA,EAAGE,CAAK,MAAMA,MAAU,MAAS;AAAA,EAAA;AAExE,SAAO,EAAE,GAAGJ,GAA0B,GAAGG,EAAA;AAC3C;"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsxs as o, jsx as t } from "react/jsx-runtime";
|
|
2
|
+
import { useId as r } from "react";
|
|
3
|
+
import a from "./Boost33Mark.module.css.js";
|
|
4
|
+
const d = 24, p = 20;
|
|
5
|
+
function M({ size: i = d, title: s, className: l }) {
|
|
6
|
+
const c = r(), e = s == null;
|
|
7
|
+
return /* @__PURE__ */ o(
|
|
8
|
+
"svg",
|
|
9
|
+
{
|
|
10
|
+
className: l != null ? `${a.mark} ${l}` : a.mark,
|
|
11
|
+
width: i,
|
|
12
|
+
height: i,
|
|
13
|
+
viewBox: "402.17 34.21 234.9 235",
|
|
14
|
+
role: e ? void 0 : "img",
|
|
15
|
+
"aria-hidden": e ? "true" : void 0,
|
|
16
|
+
"aria-labelledby": e ? void 0 : c,
|
|
17
|
+
children: [
|
|
18
|
+
!e && /* @__PURE__ */ t("title", { id: c, children: s }),
|
|
19
|
+
/* @__PURE__ */ t(
|
|
20
|
+
"path",
|
|
21
|
+
{
|
|
22
|
+
className: a.tile,
|
|
23
|
+
d: "M404.19,97c3.79-36.53,38.18-62.45,74.88-62.79q40-.37,80,0c43.66.4,77.69,34.58,78,78.28q.27,38.63,0,77.27c-.35,45.47-34.21,79.19-79.71,79.45q-38.62.23-77.24,0c-43.46-.34-77.66-34.79-77.95-78.34-.09-13,0-26.07,0-39.1m42.93-56V207c23.4,0,46.31.89,69.1-.33,14.41-.77,25.11-13.75,26.36-28.3,1.37-16-6.92-26.34-20.61-33.54,1.15-2.88,2.34-5.37,3.16-8C529,118.35,517,97.73,497.72,96,480.55,94.49,463.15,95.7,445.11,95.7Zm127.65,63.44a31.89,31.89,0,1,0-31.21-32.47A31.87,31.87,0,0,0,572.76,159.14ZM597.12,183V168.11H550.05V183Z"
|
|
24
|
+
}
|
|
25
|
+
),
|
|
26
|
+
/* @__PURE__ */ t(
|
|
27
|
+
"path",
|
|
28
|
+
{
|
|
29
|
+
className: a.ring,
|
|
30
|
+
d: "M572.76,159.14a31.89,31.89,0,1,1,32.47-31.31A31.62,31.62,0,0,1,572.76,159.14Zm.56-47.42a15.53,15.53,0,1,0,15.61,16A15.44,15.44,0,0,0,573.32,111.72Z"
|
|
31
|
+
}
|
|
32
|
+
),
|
|
33
|
+
/* @__PURE__ */ t(
|
|
34
|
+
"path",
|
|
35
|
+
{
|
|
36
|
+
className: a.tile,
|
|
37
|
+
d: "M460.7,190.94V160.11c17.05,0,33.68-.53,50.25.23,8.11.37,13.22,7.7,13,15.5s-5.75,14.69-13.73,14.94C493.9,191.3,477.58,190.94,460.7,190.94Z"
|
|
38
|
+
}
|
|
39
|
+
),
|
|
40
|
+
/* @__PURE__ */ t(
|
|
41
|
+
"path",
|
|
42
|
+
{
|
|
43
|
+
className: a.tile,
|
|
44
|
+
d: "M460.65,142.62V112.36c12.1,0,24.4-.89,36.5.33,7.46.76,11.4,7.3,11.05,15-.37,8.1-5,14-12.95,14.64C484,143.3,472.52,142.62,460.65,142.62Z"
|
|
45
|
+
}
|
|
46
|
+
),
|
|
47
|
+
/* @__PURE__ */ t(
|
|
48
|
+
"path",
|
|
49
|
+
{
|
|
50
|
+
className: a.tile,
|
|
51
|
+
d: "M573.32,111.72a15.53,15.53,0,1,1,0,31.06,15.53,15.53,0,1,1,0-31.06Z"
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
p as BOOST33_MARK_MIN_LEGIBLE_PX,
|
|
60
|
+
M as Boost33Mark
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=Boost33Mark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Boost33Mark.js","sources":["../../../src/components/Boost33Mark/Boost33Mark.tsx"],"sourcesContent":["import { useId } from 'react'\nimport styles from './Boost33Mark.module.css'\n\n/**\n * The size the mark renders at unless a caller says otherwise. 24px is the\n * Wallet's own default at both of its call sites, and it is the size\n * tests/baselines/mark-boost33.png, wordmark.png and wordmark-rail.png were\n * captured at.\n */\nconst DEFAULT_SIZE = 24\n\n/**\n * The smallest size the artwork survives, in px. Recorded, not enforced — the\n * charte's brand guide warns the monogram stops working below about 20px: the\n * bowls of the B and the hole in the o close up and the whole thing reads as a\n * dark blob. Anything smaller needs a simplified variant from the parent, not\n * this scaled down. Nothing in this package ships below it.\n *\n * This floor is the **monogram's alone**. The product marks have the opposite\n * requirement — they are drawn on a grid chosen so one path renders correctly\n * from 96px down to 20px — so do not generalise this number into a shared rule\n * when the second mark lands.\n */\nexport const BOOST33_MARK_MIN_LEGIBLE_PX = 20\n\nexport interface Boost33MarkProps {\n /**\n * Rendered width and height in px. Read BOOST33_MARK_MIN_LEGIBLE_PX before\n * going small.\n */\n size?: number\n /**\n * An accessible name. Omit it — the default — and the mark is decorative:\n * `aria-hidden`, contributing nothing to the accessibility tree. That is the\n * right answer in the lockup, where the word \"Boost33\" sits beside it and a\n * name here would only make a screen reader say it twice. Pass one only where\n * the mark stands alone as the sole carrier of meaning.\n */\n title?: string\n /** Escape hatch for a consumer that needs to position the mark. */\n className?: string\n}\n\n/**\n * The Boost33 mark — the \"Bo\" squircle monogram.\n *\n * **This artwork is not ours.** The monogram and the wordmark are set by the\n * Boost33 charte graphique and a product cannot change them; the parent's brand\n * documentation lists the monogram as \"black tile, orange letterform\" under what\n * it owns. The paths below are lifted verbatim out of the official lockup at\n * `docs/brand/logo-of-noir-orange.svg` in the Wallet repo (`boostledger`), by way\n * of its `src/ui/primitives/icons.tsx` — reproduced, not redrawn. If the mark\n * ever changes, it changes in that SVG first and this is re-extracted from it.\n * Nobody here gets to nudge a curve.\n *\n * What stood in for it in this package until B33-556 was a Stage A placeholder in\n * the specimen: an orange tile with a `<text>B</text>` typed on top. The Wallet\n * carried the same mistake — tile and letterform the wrong way round — until\n * 9 Sep 2026, which is why the original fidelity baselines showed it too. It had\n * been wrong against the charte the whole time, not just against Paper.\n *\n * How it is built, since the fills are not obvious from the path list: the first\n * path is the black squircle with the B, the o and the underscore knocked out of\n * it as counter-wound subpaths, so those three show through as white. The orange\n * ring is then drawn into the o, and the last three paths fill the B's two bowls\n * and the o's centre back to black. **Order matters between the ring and the\n * centre** — swap them and the o fills solid orange. Nothing else overlaps.\n *\n * The two `fill: none` paths in the source SVG are omitted. They are export\n * artefacts that render nothing, and dropping them does not affect the winding of\n * the path above them.\n *\n * The viewBox is the monogram's own bounding box **inside the lockup**, which is\n * why it is an offset rectangle rather than starting at the origin. Do not \"tidy\"\n * it to `0 0 …` without re-deriving the paths; they carry absolute coordinates\n * and translating one without the other silently crops the mark.\n */\nexport function Boost33Mark({ size = DEFAULT_SIZE, title, className }: Boost33MarkProps) {\n const titleId = useId()\n const decorative = title == null\n\n return (\n <svg\n className={className != null ? `${styles.mark} ${className}` : styles.mark}\n width={size}\n height={size}\n viewBox=\"402.17 34.21 234.9 235\"\n role={decorative ? undefined : 'img'}\n aria-hidden={decorative ? 'true' : undefined}\n aria-labelledby={decorative ? undefined : titleId}\n >\n {!decorative && <title id={titleId}>{title}</title>}\n {/* Tile, with the B / o / underscore knocked out of it. */}\n <path\n className={styles.tile}\n d=\"M404.19,97c3.79-36.53,38.18-62.45,74.88-62.79q40-.37,80,0c43.66.4,77.69,34.58,78,78.28q.27,38.63,0,77.27c-.35,45.47-34.21,79.19-79.71,79.45q-38.62.23-77.24,0c-43.46-.34-77.66-34.79-77.95-78.34-.09-13,0-26.07,0-39.1m42.93-56V207c23.4,0,46.31.89,69.1-.33,14.41-.77,25.11-13.75,26.36-28.3,1.37-16-6.92-26.34-20.61-33.54,1.15-2.88,2.34-5.37,3.16-8C529,118.35,517,97.73,497.72,96,480.55,94.49,463.15,95.7,445.11,95.7Zm127.65,63.44a31.89,31.89,0,1,0-31.21-32.47A31.87,31.87,0,0,0,572.76,159.14ZM597.12,183V168.11H550.05V183Z\"\n />\n {/* The o, and the only orange in the mark. */}\n <path\n className={styles.ring}\n d=\"M572.76,159.14a31.89,31.89,0,1,1,32.47-31.31A31.62,31.62,0,0,1,572.76,159.14Zm.56-47.42a15.53,15.53,0,1,0,15.61,16A15.44,15.44,0,0,0,573.32,111.72Z\"\n />\n {/* The B's two bowls and the o's centre, returned to the tile's black. */}\n <path\n className={styles.tile}\n d=\"M460.7,190.94V160.11c17.05,0,33.68-.53,50.25.23,8.11.37,13.22,7.7,13,15.5s-5.75,14.69-13.73,14.94C493.9,191.3,477.58,190.94,460.7,190.94Z\"\n />\n <path\n className={styles.tile}\n d=\"M460.65,142.62V112.36c12.1,0,24.4-.89,36.5.33,7.46.76,11.4,7.3,11.05,15-.37,8.1-5,14-12.95,14.64C484,143.3,472.52,142.62,460.65,142.62Z\"\n />\n <path\n className={styles.tile}\n d=\"M573.32,111.72a15.53,15.53,0,1,1,0,31.06,15.53,15.53,0,1,1,0-31.06Z\"\n />\n </svg>\n )\n}\n"],"names":["DEFAULT_SIZE","BOOST33_MARK_MIN_LEGIBLE_PX","Boost33Mark","size","title","className","titleId","useId","decorative","jsxs","styles","jsx"],"mappings":";;;AASA,MAAMA,IAAe,IAcRC,IAA8B;AAsDpC,SAASC,EAAY,EAAE,MAAAC,IAAOH,GAAc,OAAAI,GAAO,WAAAC,KAA+B;AACvF,QAAMC,IAAUC,EAAA,GACVC,IAAaJ,KAAS;AAE5B,SACE,gBAAAK;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWJ,KAAa,OAAO,GAAGK,EAAO,IAAI,IAAIL,CAAS,KAAKK,EAAO;AAAA,MACtE,OAAOP;AAAA,MACP,QAAQA;AAAA,MACR,SAAQ;AAAA,MACR,MAAMK,IAAa,SAAY;AAAA,MAC/B,eAAaA,IAAa,SAAS;AAAA,MACnC,mBAAiBA,IAAa,SAAYF;AAAA,MAEzC,UAAA;AAAA,QAAA,CAACE,KAAc,gBAAAG,EAAC,SAAA,EAAM,IAAIL,GAAU,UAAAF,GAAM;AAAA,QAE3C,gBAAAO;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD,EAAO;AAAA,YAClB,GAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAGJ,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD,EAAO;AAAA,YAClB,GAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAGJ,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD,EAAO;AAAA,YAClB,GAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAEJ,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD,EAAO;AAAA,YAClB,GAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAEJ,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD,EAAO;AAAA,YAClB,GAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MACJ;AAAA,IAAA;AAAA,EAAA;AAGN;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Boost33Mark.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import { ElementType, ReactNode } from 'react';
|
|
2
2
|
export interface NavItemProps {
|
|
3
3
|
/** The nav label. Truncates with an ellipsis rather than wrapping. */
|
|
4
4
|
children: ReactNode;
|
|
@@ -17,6 +17,16 @@ export interface NavItemProps {
|
|
|
17
17
|
/** Renders `count` in the primary color instead of muted. */
|
|
18
18
|
countUrgent?: boolean;
|
|
19
19
|
href?: string;
|
|
20
|
+
/**
|
|
21
|
+
* The element the linked form renders through. Defaults to a plain `a`; a
|
|
22
|
+
* consumer whose router owns navigation (Next.js, next-intl's localised
|
|
23
|
+
* `Link`) passes its own so the row routes client-side with the locale prefix
|
|
24
|
+
* intact instead of a bare anchor that full-page-reloads (B33-847). Receives
|
|
25
|
+
* `href`, `className`, `onClick` and the row's data/aria attributes unchanged,
|
|
26
|
+
* so the markup is identical to the anchor's. Only used when `href` is set;
|
|
27
|
+
* the action form stays a `button`. See docs/adr/0011.
|
|
28
|
+
*/
|
|
29
|
+
linkComponent?: ElementType;
|
|
20
30
|
onClick?: () => void;
|
|
21
31
|
}
|
|
22
|
-
export declare function NavItem({ children, icon, active, collapsed, count, countUrgent, href, onClick }: NavItemProps): import("react").JSX.Element;
|
|
32
|
+
export declare function NavItem({ children, icon, active, collapsed, count, countUrgent, href, linkComponent, onClick }: NavItemProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as e, jsxs as p, Fragment as N } from "react/jsx-runtime";
|
|
2
|
+
import a from "./NavItem.module.css.js";
|
|
3
|
+
function v({ children: i, icon: n, active: t = !1, collapsed: d = !1, count: s, countUrgent: m = !1, href: r, linkComponent: u, onClick: l }) {
|
|
4
|
+
const o = {
|
|
5
|
+
"data-active": t ? "true" : void 0,
|
|
6
|
+
"data-collapsed": d ? "true" : void 0,
|
|
7
|
+
"aria-current": t ? "page" : void 0
|
|
8
|
+
}, c = /* @__PURE__ */ p(N, { children: [
|
|
9
|
+
n != null && /* @__PURE__ */ e("span", { className: a.icon, "aria-hidden": "true", children: n }),
|
|
10
|
+
/* @__PURE__ */ e("span", { className: a.label, children: i }),
|
|
11
|
+
/* @__PURE__ */ e("span", { className: a.trailingSlot, children: s != null && /* @__PURE__ */ e("span", { className: m ? a.countUrgent : a.count, children: s }) })
|
|
12
|
+
] });
|
|
13
|
+
return r ? /* @__PURE__ */ e(u ?? "a", { className: a.row, href: r, onClick: l, ...o, children: c }) : /* @__PURE__ */ e("button", { type: "button", className: a.row, onClick: l, ...o, children: c });
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
v as NavItem
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=NavItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavItem.js","sources":["../../../src/components/NavItem/NavItem.tsx"],"sourcesContent":["import type { ElementType, ReactNode } from 'react'\nimport styles from './NavItem.module.css'\n\nexport interface NavItemProps {\n /** The nav label. Truncates with an ellipsis rather than wrapping. */\n children: ReactNode\n /**\n * The leading icon. Decorative -- the label carries the name, so pass an\n * `aria-hidden` glyph. On the rail it is the only thing that shows, the\n * label having collapsed to the accessibility tree.\n */\n icon?: ReactNode\n /** Marks this row as the current page. Sets `aria-current=\"page\"`. */\n active?: boolean\n /** Sidebar-on-the-rail state. Hides the label and trailing slot visually; the label stays in the accessibility tree. */\n collapsed?: boolean\n /** Trailing slot content. Omit to leave the slot empty -- it still reserves its width so counts line up across rows. */\n count?: number\n /** Renders `count` in the primary color instead of muted. */\n countUrgent?: boolean\n href?: string\n /**\n * The element the linked form renders through. Defaults to a plain `a`; a\n * consumer whose router owns navigation (Next.js, next-intl's localised\n * `Link`) passes its own so the row routes client-side with the locale prefix\n * intact instead of a bare anchor that full-page-reloads (B33-847). Receives\n * `href`, `className`, `onClick` and the row's data/aria attributes unchanged,\n * so the markup is identical to the anchor's. Only used when `href` is set;\n * the action form stays a `button`. See docs/adr/0011.\n */\n linkComponent?: ElementType\n onClick?: () => void\n}\n\nexport function NavItem({ children, icon, active = false, collapsed = false, count, countUrgent = false, href, linkComponent, onClick }: NavItemProps) {\n const dataProps = {\n 'data-active': active ? ('true' as const) : undefined,\n 'data-collapsed': collapsed ? ('true' as const) : undefined,\n 'aria-current': active ? ('page' as const) : undefined,\n }\n\n const content = (\n <>\n {icon != null && (\n <span className={styles.icon} aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className={styles.label}>{children}</span>\n <span className={styles.trailingSlot}>\n {count != null && <span className={countUrgent ? styles.countUrgent : styles.count}>{count}</span>}\n </span>\n </>\n )\n\n if (href) {\n const Link = linkComponent ?? 'a'\n return (\n <Link className={styles.row} href={href} onClick={onClick} {...dataProps}>\n {content}\n </Link>\n )\n }\n\n return (\n <button type=\"button\" className={styles.row} onClick={onClick} {...dataProps}>\n {content}\n </button>\n )\n}\n"],"names":["NavItem","children","icon","active","collapsed","count","countUrgent","href","linkComponent","onClick","dataProps","content","jsxs","Fragment","styles","jsx"],"mappings":";;AAkCO,SAASA,EAAQ,EAAE,UAAAC,GAAU,MAAAC,GAAM,QAAAC,IAAS,IAAO,WAAAC,IAAY,IAAO,OAAAC,GAAO,aAAAC,IAAc,IAAO,MAAAC,GAAM,eAAAC,GAAe,SAAAC,KAAyB;AACrJ,QAAMC,IAAY;AAAA,IAChB,eAAeP,IAAU,SAAmB;AAAA,IAC5C,kBAAkBC,IAAa,SAAmB;AAAA,IAClD,gBAAgBD,IAAU,SAAmB;AAAA,EAAA,GAGzCQ,IACJ,gBAAAC,EAAAC,GAAA,EACG,UAAA;AAAA,IAAAX,KAAQ,0BACN,QAAA,EAAK,WAAWY,EAAO,MAAM,eAAY,QACvC,UAAAZ,EAAA,CACH;AAAA,IAEF,gBAAAa,EAAC,QAAA,EAAK,WAAWD,EAAO,OAAQ,UAAAb,GAAS;AAAA,sBACxC,QAAA,EAAK,WAAWa,EAAO,cACrB,eAAS,QAAQ,gBAAAC,EAAC,QAAA,EAAK,WAAWT,IAAcQ,EAAO,cAAcA,EAAO,OAAQ,aAAM,EAAA,CAC7F;AAAA,EAAA,GACF;AAGF,SAAIP,IAGA,gBAAAQ,EAFWP,KAAiB,OAEtB,WAAWM,EAAO,KAAK,MAAAP,GAAY,SAAAE,GAAmB,GAAGC,GAC5D,UAAAC,EAAA,CACH,IAKF,gBAAAI,EAAC,UAAA,EAAO,MAAK,UAAS,WAAWD,EAAO,KAAK,SAAAL,GAAmB,GAAGC,GAChE,UAAAC,EAAA,CACH;AAEJ;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const t = "_row_16hr7_4", o = "_icon_16hr7_41", n = "_label_16hr7_66", _ = "_trailingSlot_16hr7_92", c = "_count_16hr7_106", r = "_countUrgent_16hr7_110", l = {
|
|
2
|
+
row: t,
|
|
3
|
+
icon: o,
|
|
4
|
+
label: n,
|
|
5
|
+
trailingSlot: _,
|
|
6
|
+
count: c,
|
|
7
|
+
countUrgent: r
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
c as count,
|
|
11
|
+
r as countUrgent,
|
|
12
|
+
l as default,
|
|
13
|
+
o as icon,
|
|
14
|
+
n as label,
|
|
15
|
+
t as row,
|
|
16
|
+
_ as trailingSlot
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=NavItem.module.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavItem.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as i, jsxs as t } from "react/jsx-runtime";
|
|
2
|
+
import { useId as a } from "react";
|
|
3
|
+
import e from "./NavSection.module.css.js";
|
|
4
|
+
function l({ label: r, children: s }) {
|
|
5
|
+
const o = a();
|
|
6
|
+
return r == null ? /* @__PURE__ */ i("div", { className: e.section, children: s }) : /* @__PURE__ */ t("div", { className: e.section, role: "group", "aria-labelledby": o, children: [
|
|
7
|
+
/* @__PURE__ */ i("p", { id: o, className: e.header, children: r }),
|
|
8
|
+
s
|
|
9
|
+
] });
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
l as NavSection
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=NavSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavSection.js","sources":["../../../src/components/NavSection/NavSection.tsx"],"sourcesContent":["import { useId, type ReactNode } from 'react'\nimport styles from './NavSection.module.css'\n\nexport interface NavSectionProps {\n /**\n * The section header -- the small uppercase label above the rows. Omit for a\n * section with no header (the sidebar's first section has none). Passed in\n * its natural case; the uppercasing is presentational.\n */\n label?: string\n /** The section's rows -- NavItems, passed in as data, never hardcoded here. */\n children: ReactNode\n}\n\n// A group of nav rows under an optional header. A labelled section is an\n// accessible group named by its header, so the rows announce with their\n// section; a headerless section is just the run of rows.\nexport function NavSection({ label, children }: NavSectionProps) {\n const headerId = useId()\n\n if (label == null) {\n return <div className={styles.section}>{children}</div>\n }\n\n return (\n <div className={styles.section} role=\"group\" aria-labelledby={headerId}>\n <p id={headerId} className={styles.header}>\n {label}\n </p>\n {children}\n </div>\n )\n}\n"],"names":["NavSection","label","children","headerId","useId","jsx","styles","jsxs"],"mappings":";;;AAiBO,SAASA,EAAW,EAAE,OAAAC,GAAO,UAAAC,KAA6B;AAC/D,QAAMC,IAAWC,EAAA;AAEjB,SAAIH,KAAS,OACJ,gBAAAI,EAAC,OAAA,EAAI,WAAWC,EAAO,SAAU,UAAAJ,GAAS,IAIjD,gBAAAK,EAAC,SAAI,WAAWD,EAAO,SAAS,MAAK,SAAQ,mBAAiBH,GAC5D,UAAA;AAAA,IAAA,gBAAAE,EAAC,OAAE,IAAIF,GAAU,WAAWG,EAAO,QAChC,UAAAL,GACH;AAAA,IACCC;AAAA,EAAA,GACH;AAEJ;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavSection.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsxs as r, jsx as l } from "react/jsx-runtime";
|
|
2
|
+
import e from "./PageHeader.module.css.js";
|
|
3
|
+
function n({ title: i, subtitle: s, actions: a }) {
|
|
4
|
+
return /* @__PURE__ */ r("header", { className: e.header, children: [
|
|
5
|
+
/* @__PURE__ */ r("div", { className: e.headings, children: [
|
|
6
|
+
/* @__PURE__ */ l("h1", { className: e.title, children: i }),
|
|
7
|
+
s != null && /* @__PURE__ */ l("p", { className: e.subtitle, children: s })
|
|
8
|
+
] }),
|
|
9
|
+
a != null && /* @__PURE__ */ l("div", { className: e.actions, children: a })
|
|
10
|
+
] });
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
n as PageHeader
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=PageHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageHeader.js","sources":["../../../src/components/PageHeader/PageHeader.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport styles from './PageHeader.module.css'\n\nexport interface PageHeaderProps {\n /** The page's name. Renders as the page heading. */\n title: ReactNode\n /** A line under the title. Omit for a title-only header. */\n subtitle?: ReactNode\n /** Trailing controls, aligned to the right edge. Omit to leave the row empty. */\n actions?: ReactNode\n}\n\nexport function PageHeader({ title, subtitle, actions }: PageHeaderProps) {\n return (\n <header className={styles.header}>\n <div className={styles.headings}>\n <h1 className={styles.title}>{title}</h1>\n {subtitle != null && <p className={styles.subtitle}>{subtitle}</p>}\n </div>\n {actions != null && <div className={styles.actions}>{actions}</div>}\n </header>\n )\n}\n"],"names":["PageHeader","title","subtitle","actions","jsxs","styles","jsx"],"mappings":";;AAYO,SAASA,EAAW,EAAE,OAAAC,GAAO,UAAAC,GAAU,SAAAC,KAA4B;AACxE,SACE,gBAAAC,EAAC,UAAA,EAAO,WAAWC,EAAO,QACxB,UAAA;AAAA,IAAA,gBAAAD,EAAC,OAAA,EAAI,WAAWC,EAAO,UACrB,UAAA;AAAA,MAAA,gBAAAC,EAAC,MAAA,EAAG,WAAWD,EAAO,OAAQ,UAAAJ,GAAM;AAAA,MACnCC,KAAY,QAAQ,gBAAAI,EAAC,OAAE,WAAWD,EAAO,UAAW,UAAAH,EAAA,CAAS;AAAA,IAAA,GAChE;AAAA,IACCC,KAAW,QAAQ,gBAAAG,EAAC,SAAI,WAAWD,EAAO,SAAU,UAAAF,EAAA,CAAQ;AAAA,EAAA,GAC/D;AAEJ;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const t = "_header_i17td_42", e = "_headings_i17td_52", s = "_title_i17td_33", i = "_subtitle_i17td_74", _ = "_actions_i17td_82", d = {
|
|
2
|
+
header: t,
|
|
3
|
+
headings: e,
|
|
4
|
+
title: s,
|
|
5
|
+
subtitle: i,
|
|
6
|
+
actions: _
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
_ as actions,
|
|
10
|
+
d as default,
|
|
11
|
+
t as header,
|
|
12
|
+
e as headings,
|
|
13
|
+
i as subtitle,
|
|
14
|
+
s as title
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=PageHeader.module.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageHeader.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
|
|
@@ -26,6 +26,17 @@ export interface ProductMarkProps {
|
|
|
26
26
|
* thing telling the four marks apart, and it is a prop rather than a wrapper
|
|
27
27
|
* `opacity-40 grayscale` filter because that lands on a mid-grey visibly
|
|
28
28
|
* darker than the grey Paper draws.
|
|
29
|
+
*
|
|
30
|
+
* **Only use this where the mark is decorative.** White on --color-neutral-300
|
|
31
|
+
* is 1.41:1, well under WCAG 1.4.11's 3:1, and the reason that is not a defect
|
|
32
|
+
* is that the criterion covers graphics *required to understand the content* --
|
|
33
|
+
* which this is not, while the mark is `aria-hidden`, the product's name sits
|
|
34
|
+
* beside it as text, and entitlement is additionally stated in words (the
|
|
35
|
+
* switcher's "Not on plan" tag). Combining `muted` with `title`, so the mark
|
|
36
|
+
* stands alone as the sole carrier of a product's identity, removes every one
|
|
37
|
+
* of those and makes the ratio bite. That combination is out of contract; no
|
|
38
|
+
* call site in this package uses it. See ADR-0012, which also records why the
|
|
39
|
+
* ground is not darkened and what to reach for if this is ever revisited.
|
|
29
40
|
*/
|
|
30
41
|
muted?: boolean;
|
|
31
42
|
/**
|
|
@@ -34,6 +45,10 @@ export interface ProductMarkProps {
|
|
|
34
45
|
* right answer in the switcher, where the product's name sits beside it and a
|
|
35
46
|
* name here would only make a screen reader say it twice. Pass one only where
|
|
36
47
|
* the mark stands alone as the sole carrier of meaning.
|
|
48
|
+
*
|
|
49
|
+
* Passing this is what takes the mark out of `muted`'s contract -- see the
|
|
50
|
+
* note there. A mark that carries meaning on its own has to be legible on its
|
|
51
|
+
* own, and the muted ground is not.
|
|
37
52
|
*/
|
|
38
53
|
title?: string;
|
|
39
54
|
/** Escape hatch for a consumer that needs to position the mark. */
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsxs as o, jsx as r, Fragment as l } from "react/jsx-runtime";
|
|
2
|
+
import { useId as a } from "react";
|
|
3
|
+
import i from "./ProductMark.module.css.js";
|
|
4
|
+
const k = 20, x = ["wallet", "score", "voice", "outbound"], f = {
|
|
5
|
+
// A credit card with its magnetic stripe: an outline card (fill none, so the
|
|
6
|
+
// tile shows through) plus a filled stripe across it.
|
|
7
|
+
wallet: /* @__PURE__ */ o(l, { children: [
|
|
8
|
+
/* @__PURE__ */ r("rect", { x: "5", y: "10", width: "30", height: "20", rx: "4", fill: "none", stroke: "currentColor", strokeWidth: "3" }),
|
|
9
|
+
/* @__PURE__ */ r("rect", { x: "5", y: "16", width: "30", height: "5", fill: "currentColor" })
|
|
10
|
+
] }),
|
|
11
|
+
// A gauge with the needle swung high: an arc, the needle, and the hub it
|
|
12
|
+
// pivots on. Arc and needle stroke at width 4 with round caps.
|
|
13
|
+
score: /* @__PURE__ */ o(l, { children: [
|
|
14
|
+
/* @__PURE__ */ r("path", { d: "M6 26 A14 14 0 0 1 34 26", fill: "none", stroke: "currentColor", strokeWidth: "4", strokeLinecap: "round" }),
|
|
15
|
+
/* @__PURE__ */ r("line", { x1: "20", y1: "26", x2: "28", y2: "14", stroke: "currentColor", strokeWidth: "4", strokeLinecap: "round" }),
|
|
16
|
+
/* @__PURE__ */ r("circle", { cx: "20", cy: "26", r: "3", fill: "currentColor" })
|
|
17
|
+
] }),
|
|
18
|
+
// A soundwave, tall in the middle: three pill bars, all centred on y=20.
|
|
19
|
+
voice: /* @__PURE__ */ o(l, { children: [
|
|
20
|
+
/* @__PURE__ */ r("rect", { x: "6", y: "14", width: "7", height: "12", rx: "3.5", fill: "currentColor" }),
|
|
21
|
+
/* @__PURE__ */ r("rect", { x: "16.5", y: "4", width: "7", height: "32", rx: "3.5", fill: "currentColor" }),
|
|
22
|
+
/* @__PURE__ */ r("rect", { x: "27", y: "14", width: "7", height: "12", rx: "3.5", fill: "currentColor" })
|
|
23
|
+
] }),
|
|
24
|
+
// An arrow leaving through the top-right: the shaft and the elbow of its head,
|
|
25
|
+
// both stroke width 4 with round caps and joins.
|
|
26
|
+
outbound: /* @__PURE__ */ o(l, { children: [
|
|
27
|
+
/* @__PURE__ */ r("line", { x1: "8", y1: "32", x2: "32", y2: "8", stroke: "currentColor", strokeWidth: "4", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
28
|
+
/* @__PURE__ */ r("path", { d: "M16 8 H32 V24", fill: "none", stroke: "currentColor", strokeWidth: "4", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
29
|
+
] })
|
|
30
|
+
};
|
|
31
|
+
function y(e) {
|
|
32
|
+
return x.includes(e);
|
|
33
|
+
}
|
|
34
|
+
function v({ slug: e, size: n = k, muted: u, title: c, className: d }) {
|
|
35
|
+
const s = a(), t = c == null, h = y(e) ? f[e] : null;
|
|
36
|
+
return /* @__PURE__ */ o(
|
|
37
|
+
"svg",
|
|
38
|
+
{
|
|
39
|
+
className: d != null ? `${i.mark} ${d}` : i.mark,
|
|
40
|
+
width: n,
|
|
41
|
+
height: n,
|
|
42
|
+
viewBox: "0 0 40 40",
|
|
43
|
+
role: t ? void 0 : "img",
|
|
44
|
+
"aria-hidden": t ? "true" : void 0,
|
|
45
|
+
"aria-labelledby": t ? void 0 : s,
|
|
46
|
+
children: [
|
|
47
|
+
!t && /* @__PURE__ */ r("title", { id: s, children: c }),
|
|
48
|
+
/* @__PURE__ */ r(
|
|
49
|
+
"rect",
|
|
50
|
+
{
|
|
51
|
+
className: i.ground,
|
|
52
|
+
width: "40",
|
|
53
|
+
height: "40",
|
|
54
|
+
style: { fill: u ? "var(--color-neutral-300)" : "var(--color-neutral-950)" }
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
h && /* @__PURE__ */ r(
|
|
58
|
+
"g",
|
|
59
|
+
{
|
|
60
|
+
transform: "translate(10 10) scale(0.5)",
|
|
61
|
+
style: { color: "var(--color-primary-foreground)" },
|
|
62
|
+
children: h
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
x as PRODUCT_SLUGS,
|
|
71
|
+
v as ProductMark
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=ProductMark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProductMark.js","sources":["../../../src/components/ProductMark/ProductMark.tsx"],"sourcesContent":["import { useId, type ReactNode } from 'react'\nimport styles from './ProductMark.module.css'\n\n/**\n * The size the mark renders at unless a caller says otherwise. 20px is the\n * Wallet's own default at its call sites, and the size the four\n * tests/baselines/productmark-*.png were captured at: a 20px tile in the 24px\n * gutter the specimen crop uses either side -> 68px CSS -> 136 device px at\n * deviceScaleFactor 2. Changing it moves four apps.\n *\n * There is deliberately no minimum-legible floor here, unlike Boost33Mark. That\n * floor is the monogram's alone -- the bowls of the B close up below ~20px. The\n * product marks have the opposite property: each is one path on a 40-unit grid\n * with a quarter-side corner, chosen so it renders correctly from Paper's 96px\n * down to 20px. Do not generalise Boost33Mark's floor into a shared rule.\n */\nconst DEFAULT_SIZE = 20\n\n/**\n * The four products Identity serves, as one list. Everything else keys off it:\n * ProductSlug is derived from it, and GLYPHS is typed against it so adding a\n * slug without artwork is a compile error rather than a mark that silently\n * draws nothing. These are Identity's *slugs*, not display names -- the Wallet\n * keys its own record on `'Boost Score' | ... | 'Wallet'`, which a rename\n * breaks, and that is the exact trap this ordering avoids.\n */\nexport const PRODUCT_SLUGS = ['wallet', 'score', 'voice', 'outbound'] as const\n\n/** One of Identity's four product slugs. */\nexport type ProductSlug = (typeof PRODUCT_SLUGS)[number]\n\n/**\n * The four product glyphs, lifted verbatim from `boostledger`'s\n * `src/ui/primitives/icons.tsx` (the `GLYPHS` record, as of `837d85d`) rather\n * than redrawn from any written description. Redrawing them from\n * `docs/mintlify/system/product-marks.mdx` is how PR #4 got all four wrong and\n * reintroduced the retired one-orange-element construction; if any document\n * disagrees with that file, that file wins. See B33-562.\n *\n * Each glyph is drawn on its own full 40-unit grid and inset into the middle 20\n * of the tile by the `translate(10 10) scale(0.5)` group below. The stroke\n * widths are right on that grid -- do not \"correct\" them to compensate for the\n * scale, the scale is what puts the stroke at the weight Paper draws. Every\n * element paints in `currentColor` (the tile's white glyph ink) or `none`;\n * there is no colour of any kind in here, which is what tells the four marks\n * apart by shape and never by hue.\n *\n * Typing this `Record<ProductSlug, ReactNode>` is load-bearing: a fifth slug\n * added to PRODUCT_SLUGS without a glyph here stops the build.\n */\nconst GLYPHS: Record<ProductSlug, ReactNode> = {\n // A credit card with its magnetic stripe: an outline card (fill none, so the\n // tile shows through) plus a filled stripe across it.\n wallet: (\n <>\n <rect x=\"5\" y=\"10\" width=\"30\" height=\"20\" rx=\"4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" />\n <rect x=\"5\" y=\"16\" width=\"30\" height=\"5\" fill=\"currentColor\" />\n </>\n ),\n // A gauge with the needle swung high: an arc, the needle, and the hub it\n // pivots on. Arc and needle stroke at width 4 with round caps.\n score: (\n <>\n <path d=\"M6 26 A14 14 0 0 1 34 26\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"4\" strokeLinecap=\"round\" />\n <line x1=\"20\" y1=\"26\" x2=\"28\" y2=\"14\" stroke=\"currentColor\" strokeWidth=\"4\" strokeLinecap=\"round\" />\n <circle cx=\"20\" cy=\"26\" r=\"3\" fill=\"currentColor\" />\n </>\n ),\n // A soundwave, tall in the middle: three pill bars, all centred on y=20.\n voice: (\n <>\n <rect x=\"6\" y=\"14\" width=\"7\" height=\"12\" rx=\"3.5\" fill=\"currentColor\" />\n <rect x=\"16.5\" y=\"4\" width=\"7\" height=\"32\" rx=\"3.5\" fill=\"currentColor\" />\n <rect x=\"27\" y=\"14\" width=\"7\" height=\"12\" rx=\"3.5\" fill=\"currentColor\" />\n </>\n ),\n // An arrow leaving through the top-right: the shaft and the elbow of its head,\n // both stroke width 4 with round caps and joins.\n outbound: (\n <>\n <line x1=\"8\" y1=\"32\" x2=\"32\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M16 8 H32 V24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </>\n ),\n}\n\nfunction isProductSlug(slug: string): slug is ProductSlug {\n return (PRODUCT_SLUGS as readonly string[]).includes(slug)\n}\n\nexport interface ProductMarkProps {\n /**\n * Identity's product slug. An unknown one -- a product the served registry\n * carries but this package has no artwork for yet -- draws the bare tile\n * rather than throwing (ADR-0003's safe degrade), so the registry can run\n * ahead of a mark release.\n */\n slug: string\n /** Rendered width and height in px. Defaults to 20, the Wallet's own default. */\n size?: number\n /**\n * Dims the tile for a product the account is not entitled to -- the switcher's\n * unowned rows need it. It swaps the **ground only**, to --color-neutral-300;\n * the glyph stays white. Fading the glyph too would cost the shape the one\n * thing telling the four marks apart, and it is a prop rather than a wrapper\n * `opacity-40 grayscale` filter because that lands on a mid-grey visibly\n * darker than the grey Paper draws.\n *\n * **Only use this where the mark is decorative.** White on --color-neutral-300\n * is 1.41:1, well under WCAG 1.4.11's 3:1, and the reason that is not a defect\n * is that the criterion covers graphics *required to understand the content* --\n * which this is not, while the mark is `aria-hidden`, the product's name sits\n * beside it as text, and entitlement is additionally stated in words (the\n * switcher's \"Not on plan\" tag). Combining `muted` with `title`, so the mark\n * stands alone as the sole carrier of a product's identity, removes every one\n * of those and makes the ratio bite. That combination is out of contract; no\n * call site in this package uses it. See ADR-0012, which also records why the\n * ground is not darkened and what to reach for if this is ever revisited.\n */\n muted?: boolean\n /**\n * An accessible name. Omit it -- the default -- and the mark is decorative:\n * `aria-hidden`, contributing nothing to the accessibility tree. That is the\n * right answer in the switcher, where the product's name sits beside it and a\n * name here would only make a screen reader say it twice. Pass one only where\n * the mark stands alone as the sole carrier of meaning.\n *\n * Passing this is what takes the mark out of `muted`'s contract -- see the\n * note there. A mark that carries meaning on its own has to be legible on its\n * own, and the muted ground is not.\n */\n title?: string\n /** Escape hatch for a consumer that needs to position the mark. */\n className?: string\n}\n\n/**\n * The tile-and-glyph mark for one Boost33 product -- a rounded --color-neutral-950\n * square with the product's glyph in --color-primary-foreground. The four marks\n * share one palette and are told apart by shape alone; there is zero brand\n * orange in any of them.\n */\nexport function ProductMark({ slug, size = DEFAULT_SIZE, muted, title, className }: ProductMarkProps) {\n const titleId = useId()\n const decorative = title == null\n const glyph = isProductSlug(slug) ? GLYPHS[slug] : null\n\n return (\n <svg\n className={className != null ? `${styles.mark} ${className}` : styles.mark}\n width={size}\n height={size}\n viewBox=\"0 0 40 40\"\n role={decorative ? undefined : 'img'}\n aria-hidden={decorative ? 'true' : undefined}\n aria-labelledby={decorative ? undefined : titleId}\n >\n {!decorative && <title id={titleId}>{title}</title>}\n {/* The tile. Fill set inline, next to the muted decision that chooses it;\n the corner radius comes from the class (see ProductMark.module.css). */}\n <rect\n className={styles.ground}\n width=\"40\"\n height=\"40\"\n style={{ fill: muted ? 'var(--color-neutral-300)' : 'var(--color-neutral-950)' }}\n />\n {glyph && (\n <g\n transform=\"translate(10 10) scale(0.5)\"\n style={{ color: 'var(--color-primary-foreground)' }}\n >\n {glyph}\n </g>\n )}\n </svg>\n )\n}\n"],"names":["DEFAULT_SIZE","PRODUCT_SLUGS","GLYPHS","jsxs","Fragment","jsx","isProductSlug","slug","ProductMark","size","muted","title","className","titleId","useId","decorative","glyph","styles"],"mappings":";;;AAgBA,MAAMA,IAAe,IAURC,IAAgB,CAAC,UAAU,SAAS,SAAS,UAAU,GAwB9DC,IAAyC;AAAA;AAAA;AAAA,EAG7C,QACE,gBAAAC,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAC,EAAC,UAAK,GAAE,KAAI,GAAE,MAAK,OAAM,MAAK,QAAO,MAAK,IAAG,KAAI,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI;AAAA,IACnG,gBAAAA,EAAC,QAAA,EAAK,GAAE,KAAI,GAAE,MAAK,OAAM,MAAK,QAAO,KAAI,MAAK,eAAA,CAAe;AAAA,EAAA,GAC/D;AAAA;AAAA;AAAA,EAIF,OACE,gBAAAF,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAC,EAAC,QAAA,EAAK,GAAE,4BAA2B,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,QAAA,CAAQ;AAAA,IAC3G,gBAAAA,EAAC,QAAA,EAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ;AAAA,IAClG,gBAAAA,EAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI,MAAK,eAAA,CAAe;AAAA,EAAA,GACpD;AAAA;AAAA,EAGF,OACE,gBAAAF,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAC,EAAC,QAAA,EAAK,GAAE,KAAI,GAAE,MAAK,OAAM,KAAI,QAAO,MAAK,IAAG,OAAM,MAAK,gBAAe;AAAA,IACtE,gBAAAA,EAAC,QAAA,EAAK,GAAE,QAAO,GAAE,KAAI,OAAM,KAAI,QAAO,MAAK,IAAG,OAAM,MAAK,gBAAe;AAAA,IACxE,gBAAAA,EAAC,QAAA,EAAK,GAAE,MAAK,GAAE,MAAK,OAAM,KAAI,QAAO,MAAK,IAAG,OAAM,MAAK,eAAA,CAAe;AAAA,EAAA,GACzE;AAAA;AAAA;AAAA,EAIF,UACE,gBAAAF,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAC,EAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,KAAI,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ;AAAA,IACvH,gBAAAA,EAAC,QAAA,EAAK,GAAE,iBAAgB,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,QAAA,CAAQ;AAAA,EAAA,EAAA,CACzH;AAEJ;AAEA,SAASC,EAAcC,GAAmC;AACxD,SAAQN,EAAoC,SAASM,CAAI;AAC3D;AAsDO,SAASC,EAAY,EAAE,MAAAD,GAAM,MAAAE,IAAOT,GAAc,OAAAU,GAAO,OAAAC,GAAO,WAAAC,KAA+B;AACpG,QAAMC,IAAUC,EAAA,GACVC,IAAaJ,KAAS,MACtBK,IAAQV,EAAcC,CAAI,IAAIL,EAAOK,CAAI,IAAI;AAEnD,SACE,gBAAAJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWS,KAAa,OAAO,GAAGK,EAAO,IAAI,IAAIL,CAAS,KAAKK,EAAO;AAAA,MACtE,OAAOR;AAAA,MACP,QAAQA;AAAA,MACR,SAAQ;AAAA,MACR,MAAMM,IAAa,SAAY;AAAA,MAC/B,eAAaA,IAAa,SAAS;AAAA,MACnC,mBAAiBA,IAAa,SAAYF;AAAA,MAEzC,UAAA;AAAA,QAAA,CAACE,KAAc,gBAAAV,EAAC,SAAA,EAAM,IAAIQ,GAAU,UAAAF,GAAM;AAAA,QAG3C,gBAAAN;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWY,EAAO;AAAA,YAClB,OAAM;AAAA,YACN,QAAO;AAAA,YACP,OAAO,EAAE,MAAMP,IAAQ,6BAA6B,2BAAA;AAAA,UAA2B;AAAA,QAAA;AAAA,QAEhFM,KACC,gBAAAX;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO,EAAE,OAAO,kCAAA;AAAA,YAEf,UAAAW;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAIR;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProductMark.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|