@boost33/ui 0.6.0 → 0.7.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.
@@ -6,95 +6,76 @@
6
6
  *
7
7
  * **Module-internal since B33-1269, and it has to stay that way.** `src/index.ts`
8
8
  * publishes `hasProductMark` below and neither this list nor `ProductSlug`. A
9
- * `const` assertion over four strings made an artwork inventory part of the
9
+ * `const` assertion over these strings made an artwork inventory part of the
10
10
  * published type contract: a consumer could write `Record<ProductSlug, ...>` or
11
- * switch exhaustively over it, and then artwork landing for a fifth product --
11
+ * switch exhaustively over it, and then artwork landing for another product --
12
12
  * the thing this package exists to ship -- would be a breaking change for them.
13
13
  * Nothing published is typed `ProductSlug` anyway; every slug prop is `string` on
14
14
  * purpose, so Identity's registry may run ahead of a mark release (ADR-0003, and
15
15
  * `slug` below). So the union's only real job was answering "which slugs have
16
16
  * artwork", and `hasProductMark` answers that without freezing the list.
17
+ * B33-1670 widening this from four slugs to ten is the proof: it adds drawings
18
+ * and flips six `hasProductMark` answers to true, and breaks nothing a consumer
19
+ * could have typed.
17
20
  *
18
21
  * The tests and the specimen read both names by deep import, which is how
19
22
  * everything in this repo reaches into `src/`. A consumer cannot: `package.json`
20
23
  * exports `.`, `./style.css` and `./theme.css`, and nothing else.
21
24
  *
22
- * **It is no longer the whole of Identity's registry, and the difference is
23
- * deliberate.** Identity serves five slugs: these four plus `brokers` (B33-1158,
24
- * "Boost Brokers"). This package has no `brokers` glyph, so that row draws the
25
- * bare tile through the safe degrade below -- see "The fifth slug" underneath.
26
- *
27
- * **Transcribed from `boost33-identity/src/lib/productRegistry.ts`** -- its
28
- * `REGISTRY_SLUGS`, which is `PRODUCTS` from `src/config/products.ts` plus
29
- * `WALLET_SLUG`. That file is the source of truth and this is a copy of it in
30
- * another repository, which is a thing that drifts. It already did: until
31
- * B33-1043 this list read `wallet | score | voice | outbound` while this comment
32
- * asserted it was Identity's, so three of the four rows of a switcher fed
33
- * straight from `GET /api/v1/products` drew the bare tile (see `slug` below) and
34
- * nothing anywhere failed.
25
+ * **It is the whole of Identity's registry: all ten slugs, every one with a
26
+ * mark.** Transcribed from `boost33-identity/src/lib/productRegistry.ts` -- its
27
+ * `REGISTRY_SLUGS`, which is `PRODUCTS` from `src/config/products.ts`
28
+ * (boostscore, boostvoice, boostoutbound, brokers, boosttrade, boostfunding)
29
+ * plus `RESULTS_SLUG`, `PASSPORT_SLUG`, `PIPE_SLUG` and `WALLET_SLUG`. That file
30
+ * is the source of truth and this is a copy of it in another repository, which
31
+ * is a thing that drifts. It already did: until B33-1043 this list read
32
+ * `wallet | score | voice | outbound` while its comment asserted it was
33
+ * Identity's, so three of the four rows of a switcher fed straight from
34
+ * `GET /api/v1/products` drew the bare tile (see `slug` below) and nothing
35
+ * anywhere failed.
35
36
  *
36
37
  * Identity is not the side that renames. ADR-0003 records the shorter slugs as
37
38
  * considered and rejected: these match the `?app=` keys live campaign URLs
38
39
  * already carry, so renaming them means those links grant nothing on sign-up.
40
+ * The same holds for `boostvoice`, whose mark is already the Content pencil:
41
+ * the product is being renamed Boost Content, and the display name moves on
42
+ * Identity's side (B33-1672) while the slug stays.
39
43
  *
40
44
  * `tests/product-mark.test.tsx` pins this list against a second transcription of
41
45
  * the same source, so the two repositories cannot part company in silence again.
42
- * That pin is what the old comment's assertion was standing in for, and it now
43
- * pins the gap as well as the overlap: it names `brokers` as the one served slug
44
- * with no glyph here, so a *sixth* product, or artwork landing for this one,
45
- * fails rather than passing quietly.
46
+ * The pin also keeps a list of served slugs this package deliberately draws
47
+ * nothing for. That list is empty since B33-1670, and it stays in the test so an
48
+ * eleventh product Identity serves before its mark lands is a recorded decision
49
+ * rather than a quiet pass.
46
50
  *
47
51
  * The *order* is this package's own and not Identity's -- `REGISTRY_SLUGS` ends
48
- * with `wallet` where this begins with it. Nothing reads a render order off this
49
- * list: a switcher draws the order its consumer was served (`AppSwitcher`), and
50
- * the only thing this order sets is the left-to-right run of frames in the
51
- * ProductMark specimen.
52
- *
53
- * ── The fifth slug ───────────────────────────────────────────────────────────
54
- *
55
- * **`brokers` is absent because no Brokers artwork exists to lift, not because
56
- * nobody got to it.** The four glyphs below were taken verbatim out of
57
- * `boostledger/src/ui/primitives/icons.tsx`, whose own `GLYPHS` is typed
58
- * `Record<ProductName, ReactNode>` over exactly four display names. There is no
59
- * Brokers mark in that file, none in `boost33-brand-hub`, and none in this
60
- * repository. The hub renders the product as a text quick-link and no mark at
61
- * all.
62
- *
63
- * So drawing one here would not be transcribing a mark, it would be inventing
64
- * one -- and the comment on GLYPHS below records what that costs: PR #4 redrew
65
- * all four from a written description, got all four wrong, and reintroduced the
66
- * retired one-orange-element construction. An invented fifth mark is worse than
67
- * that was, because it has nothing to be caught against. A human captures the
68
- * first baseline at the fidelity gate, which would make the invention the
69
- * referent, and it looks equally settled either way afterwards (CLAUDE.md, "an
70
- * agent that picks one and builds it has invented a referent").
71
- *
72
- * The degrade is also the mildest it will ever be. Identity serves `brokers` as
73
- * `live: false` -- the space is still being built -- so the switcher row carries
74
- * the "Soon" tag beside the bare tile, which reads as a product that has not
75
- * arrived rather than as a drawing that failed to load. That stops being true
76
- * the day Brokers ships.
77
- *
78
- * **To close it:** get the mark drawn where the other four live
79
- * (`boostledger/src/ui/primitives/icons.tsx`), lift it here verbatim, add
80
- * `brokers` to this list, and let a human approve `productmark-brokers.png` at a
81
- * gate. Not in that order optional: this list is what GLYPHS is typed against,
82
- * so adding the slug without the artwork stops the build, which is the one part
83
- * of this that cannot go wrong quietly.
84
- *
85
- * **And since B33-1269 that is an ordinary addition rather than a breaking
86
- * change.** This list is not published, so widening it widens nothing a consumer
87
- * has typed against: a fifth entry adds a drawing where there was a bare tile and
88
- * flips `hasProductMark('brokers')` from false to true. Until then it was a
89
- * major-bump-shaped change to ship a picture, which is the wrong price for the
90
- * thing this package is for.
52
+ * with `wallet` where this begins with it, then follows Identity's order for the
53
+ * other nine. Nothing reads a render order off this list: a switcher draws the
54
+ * order its consumer was served (`AppSwitcher`), and the only thing this order
55
+ * sets is the left-to-right run of frames in the ProductMark specimen, where the
56
+ * four slugs that have carried a mark since 0.1 keep the first four places.
57
+ *
58
+ * ── Brokers, and the six that arrived with it ────────────────────────────────
59
+ *
60
+ * From 0.4.0 to 0.6.0 Identity served `brokers` and this package drew it as the
61
+ * bare tile, deliberately: no Brokers artwork existed in any repository to lift,
62
+ * and drawing one here would have been inventing a referent rather than
63
+ * transcribing a mark (PR #4 redrew the first four from a written description
64
+ * and got all four wrong). Identity then grew `boosttrade`, `boostfunding`,
65
+ * `boostresults`, `passport` and `pipe`, all served with no mark here either.
66
+ *
67
+ * B33-1669 closed it the way the old comment said it had to be closed: the
68
+ * marks were drawn where the others live (`boostledger/src/ui/primitives/icons.tsx`),
69
+ * for all ten products at once, and B33-1670 lifted them here verbatim. The
70
+ * part a commit cannot do is still outstanding when this lands -- a human
71
+ * approves `productmark-<slug>.png` for each of the ten at the fidelity gate
72
+ * (tests/baselines/README.md).
91
73
  */
92
- export declare const PRODUCT_SLUGS: readonly ["wallet", "boostscore", "boostvoice", "boostoutbound"];
74
+ export declare const PRODUCT_SLUGS: readonly ["wallet", "boostscore", "boostvoice", "boostoutbound", "brokers", "boosttrade", "boostfunding", "boostresults", "passport", "pipe"];
93
75
  /**
94
- * One of the slugs this package draws a mark for. Not every slug Identity serves
95
- * -- see above -- and not published either, for the reason recorded there. What
96
- * this type is for is typing GLYPHS, so the list and the artwork cannot part
97
- * company.
76
+ * One of the slugs this package draws a mark for. Not published, for the reason
77
+ * recorded above. What this type is for is typing GLYPHS, so the list and the
78
+ * artwork cannot part company.
98
79
  */
99
80
  export type ProductSlug = (typeof PRODUCT_SLUGS)[number];
100
81
  /**
@@ -104,9 +85,9 @@ export type ProductSlug = (typeof PRODUCT_SLUGS)[number];
104
85
  * **Ask this rather than matching a slug against a union of known slugs.** The
105
86
  * set of slugs with artwork is this package's inventory, not a vocabulary:
106
87
  * Identity owns which products exist (ADR-0003) and this list grows whenever a
107
- * drawing lands. `brokers` is the one slug Identity serves today that there is no
108
- * glyph here for -- see "The fifth slug" above. A caller that pattern-matches a
109
- * union is pinned to whichever inventory it compiled against; a caller that asks
88
+ * drawing lands. Since B33-1670 every slug Identity serves has a mark, and the
89
+ * next product Identity adds will be served before its mark ships here. A
90
+ * caller that pattern-matches a union is pinned to whichever inventory it compiled against; a caller that asks
110
91
  * this gets the installed version's answer, and keeps working when the next mark
111
92
  * ships.
112
93
  *
@@ -135,9 +116,15 @@ export interface ProductMarkProps {
135
116
  size?: number;
136
117
  /**
137
118
  * Dims the tile for a product the account is not entitled to -- the switcher's
138
- * unowned rows need it. It swaps the **ground only**, to --color-neutral-300;
139
- * the glyph stays white. Fading the glyph too would cost the shape the one
140
- * thing telling the four marks apart, and it is a prop rather than a wrapper
119
+ * unowned and unbuilt rows need it. The tile ground greys to
120
+ * --color-neutral-300, and the cut-outs painted in the tile colour grey with
121
+ * it. The glyph stays white, and **the orange accent turns white too** (Jamal,
122
+ * 29 Oct 2026, B33-1669): a product the account does not own spends no
123
+ * orange. Two marks take the drawing from Paper's "Option: no orange" row to
124
+ * stay legible without the accent -- Outbound gains a fold line in the tile
125
+ * colour between its two wings, and Passport's globe flips to the tile colour
126
+ * with white lines. Fading the glyph instead would cost the shape the one
127
+ * thing telling the marks apart, and it is a prop rather than a wrapper
141
128
  * `opacity-40 grayscale` filter because that lands on a mid-grey visibly
142
129
  * darker than the grey Paper draws.
143
130
  *
@@ -151,6 +138,8 @@ export interface ProductMarkProps {
151
138
  * of those and makes the ratio bite. That combination is out of contract; no
152
139
  * call site in this package uses it. See ADR-0012, which also records why the
153
140
  * ground is not darkened and what to reach for if this is ever revisited.
141
+ * Since the accent turned white on a muted tile, every ink on that tile is the
142
+ * same white ADR-0012 measured, so its 1.41:1 is still the only ratio there is.
154
143
  */
155
144
  muted?: boolean;
156
145
  /**
@@ -170,8 +159,9 @@ export interface ProductMarkProps {
170
159
  }
171
160
  /**
172
161
  * The tile-and-glyph mark for one Boost33 product -- a rounded --color-neutral-950
173
- * square with the product's glyph in --color-primary-foreground. The four marks
174
- * share one palette and are told apart by shape alone; there is zero brand
175
- * orange in any of them.
162
+ * square with the product's glyph in --color-primary-foreground and one accent
163
+ * in --color-primary. The ten marks share one palette and are told apart by
164
+ * shape; the accent is the same orange in every one of them, so it identifies
165
+ * nothing.
176
166
  */
177
167
  export declare function ProductMark({ slug, size, muted, title, className }: ProductMarkProps): import("react").JSX.Element;
@@ -1,77 +1,231 @@
1
- import { jsxs as t, jsx as r, Fragment as n } from "react/jsx-runtime";
2
- import { useId as k } from "react";
3
- import i from "./ProductMark.module.css.js";
4
- const x = 20, f = ["wallet", "boostscore", "boostvoice", "boostoutbound"], y = {
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__ */ t(n, { 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
- boostscore: /* @__PURE__ */ t(n, { 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
- boostvoice: /* @__PURE__ */ t(n, { 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
- boostoutbound: /* @__PURE__ */ t(n, { 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
- ] })
1
+ import { jsxs as l, jsx as r, Fragment as e } from "react/jsx-runtime";
2
+ import { useId as L } from "react";
3
+ import a from "./ProductMark.module.css.js";
4
+ const w = 20, g = [
5
+ "wallet",
6
+ "boostscore",
7
+ "boostvoice",
8
+ "boostoutbound",
9
+ "brokers",
10
+ "boosttrade",
11
+ "boostfunding",
12
+ "boostresults",
13
+ "passport",
14
+ "pipe"
15
+ ], o = "var(--color-primary-foreground)", b = "var(--color-primary)", M = "var(--color-neutral-950)", m = "var(--color-neutral-300)", d = 40, v = 0.62, W = 24, E = {
16
+ // wallet (upstream "Wallet"). A wallet with a card tucked behind its flap and
17
+ // an orange clasp.
18
+ wallet: {
19
+ optical: 0.94,
20
+ draw: ({ tile: t, accent: i }) => /* @__PURE__ */ l(e, { children: [
21
+ /* @__PURE__ */ r(
22
+ "path",
23
+ {
24
+ d: "M5 7 L15.4 3.1 A1.2 1.2 0 0 1 17 4 L17.6 7 Z",
25
+ fill: o,
26
+ stroke: o,
27
+ strokeWidth: "1",
28
+ strokeLinejoin: "round"
29
+ }
30
+ ),
31
+ /* @__PURE__ */ r("rect", { x: "2.5", y: "6.5", width: "19", height: "15", rx: "3", fill: o }),
32
+ /* @__PURE__ */ r("rect", { x: "14.5", y: "10.75", width: "9", height: "6.5", rx: "2.5", fill: t }),
33
+ /* @__PURE__ */ r("circle", { cx: "17.75", cy: "14", r: "1.5", fill: i })
34
+ ] })
35
+ },
36
+ // boostscore (upstream "Boost Score"). A target: a white ring around an orange
37
+ // bull's-eye.
38
+ boostscore: {
39
+ optical: 1,
40
+ draw: ({ tile: t, accent: i }) => /* @__PURE__ */ l(e, { children: [
41
+ /* @__PURE__ */ r("circle", { cx: "12", cy: "12", r: "10", fill: o }),
42
+ /* @__PURE__ */ r("circle", { cx: "12", cy: "12", r: "7", fill: t }),
43
+ /* @__PURE__ */ r("circle", { cx: "12", cy: "12", r: "4", fill: i })
44
+ ] })
45
+ },
46
+ // boostvoice (upstream "Boost Voice"). The CONTENT pencil: the product is being
47
+ // renamed Boost Content and the mark is already drawn for the new name. The
48
+ // slug stays `boostvoice`; the display rename is Identity's (B33-1672).
49
+ boostvoice: {
50
+ optical: 1,
51
+ draw: ({ tile: t, accent: i }) => /* @__PURE__ */ l(e, { children: [
52
+ /* @__PURE__ */ r(
53
+ "path",
54
+ {
55
+ d: "M15.8 3.6 A2 2 0 0 1 18.6 3.6 L20.4 5.4 A2 2 0 0 1 20.4 8.2 L9 19.6 L4 20.5 L4.4 15 Z",
56
+ fill: o,
57
+ stroke: o,
58
+ strokeWidth: "1",
59
+ strokeLinejoin: "round"
60
+ }
61
+ ),
62
+ /* @__PURE__ */ r("path", { d: "M13.4 6 L18 10.6", stroke: t, strokeWidth: "1.6", strokeLinecap: "round" }),
63
+ /* @__PURE__ */ r("rect", { x: "13", y: "18.25", width: "8.5", height: "2.75", rx: "1.375", fill: i })
64
+ ] })
65
+ },
66
+ // boostoutbound (upstream "Boost Outbound"). A paper plane, its near wing orange.
67
+ boostoutbound: {
68
+ optical: 1,
69
+ draw: ({ tile: t, accent: i }) => /* @__PURE__ */ l(e, { children: [
70
+ /* @__PURE__ */ r(
71
+ "path",
72
+ {
73
+ d: "M21 3 L3 10.4 L10.2 13.8 Z",
74
+ fill: o,
75
+ stroke: o,
76
+ strokeWidth: "1.5",
77
+ strokeLinejoin: "round"
78
+ }
79
+ ),
80
+ /* @__PURE__ */ r(
81
+ "path",
82
+ {
83
+ d: "M21 3 L10.2 13.8 L13.6 21 Z",
84
+ fill: i,
85
+ stroke: i,
86
+ strokeWidth: "1.5",
87
+ strokeLinejoin: "round"
88
+ }
89
+ ),
90
+ i === o && /* @__PURE__ */ r("path", { d: "M20 4 L10.2 13.8", stroke: t, strokeWidth: "1.4", strokeLinecap: "round" })
91
+ ] })
92
+ },
93
+ // brokers (upstream "Boost Brokers"). Two people, the one behind in orange; a
94
+ // tile-coloured outline separates the white figure in front from it.
95
+ brokers: {
96
+ optical: 1,
97
+ draw: ({ tile: t, accent: i }) => /* @__PURE__ */ l(e, { children: [
98
+ /* @__PURE__ */ r("circle", { cx: "16.5", cy: "7.5", r: "3.25", fill: i }),
99
+ /* @__PURE__ */ r("path", { d: "M11 20 A5.5 5.5 0 0 1 22 20 Z", fill: i }),
100
+ /* @__PURE__ */ r("circle", { cx: "9", cy: "7.5", r: "3.75", fill: o, stroke: t, strokeWidth: "1.5" }),
101
+ /* @__PURE__ */ r(
102
+ "path",
103
+ {
104
+ d: "M2 20.5 A7 7 0 0 1 16 20.5 Z",
105
+ fill: o,
106
+ stroke: t,
107
+ strokeWidth: "1.5",
108
+ strokeLinejoin: "round"
109
+ }
110
+ )
111
+ ] })
112
+ },
113
+ // boosttrade (upstream "Boost Off Market"). A key -- something not on the open
114
+ // market -- with an orange bow.
115
+ boosttrade: {
116
+ optical: 1,
117
+ draw: ({ tile: t, accent: i }) => /* @__PURE__ */ l(e, { children: [
118
+ /* @__PURE__ */ r("rect", { x: "11", y: "10.6", width: "11", height: "2.8", rx: "1.4", fill: o }),
119
+ /* @__PURE__ */ r("rect", { x: "15.6", y: "11", width: "2.8", height: "5", rx: "1.2", fill: o }),
120
+ /* @__PURE__ */ r("rect", { x: "19.2", y: "11", width: "2.8", height: "3.8", rx: "1.2", fill: o }),
121
+ /* @__PURE__ */ r("circle", { cx: "7.5", cy: "12", r: "5.5", fill: o }),
122
+ /* @__PURE__ */ r("circle", { cx: "7.5", cy: "12", r: "2.6", fill: t }),
123
+ /* @__PURE__ */ r("circle", { cx: "7.5", cy: "12", r: "1.6", fill: i })
124
+ ] })
125
+ },
126
+ // boostfunding (upstream "Boost Financing"). A banknote with its coin, an
127
+ // orange note stacked behind it.
128
+ boostfunding: {
129
+ optical: 1,
130
+ draw: ({ tile: t, accent: i }) => /* @__PURE__ */ l(e, { children: [
131
+ /* @__PURE__ */ r("rect", { x: "4.75", y: "4.5", width: "17", height: "11", rx: "2.5", fill: i }),
132
+ /* @__PURE__ */ r("rect", { x: "1", y: "8.25", width: "18.75", height: "12.5", rx: "3.25", fill: t }),
133
+ /* @__PURE__ */ r("rect", { x: "2.25", y: "9.5", width: "16.25", height: "10", rx: "2", fill: o }),
134
+ /* @__PURE__ */ r("circle", { cx: "10.375", cy: "14.5", r: "2.75", fill: t })
135
+ ] })
136
+ },
137
+ // boostresults (upstream "Boost Activity"). A pulse line running into an
138
+ // orange dot -- activity, now.
139
+ boostresults: {
140
+ optical: 1,
141
+ draw: ({ accent: t }) => /* @__PURE__ */ l(e, { children: [
142
+ /* @__PURE__ */ r(
143
+ "path",
144
+ {
145
+ d: "M2.5 12.5 H6 L9 5 L14 19 L16.6 12.5 H17",
146
+ fill: "none",
147
+ stroke: o,
148
+ strokeWidth: "2.5",
149
+ strokeLinecap: "round",
150
+ strokeLinejoin: "round"
151
+ }
152
+ ),
153
+ /* @__PURE__ */ r("circle", { cx: "20", cy: "12.5", r: "2.5", fill: t })
154
+ ] })
155
+ },
156
+ // passport (upstream "Boost Passport"). A passport booklet with an orange globe
157
+ // and a name bar. The globe's meridian and equator are dropped below 24px (see
158
+ // the constant above).
159
+ passport: {
160
+ optical: 0.94,
161
+ draw: ({ tile: t, accent: i, size: c }) => /* @__PURE__ */ l(e, { children: [
162
+ /* @__PURE__ */ r("rect", { x: "4.5", y: "2", width: "15", height: "20", rx: "2.5", fill: o }),
163
+ /* @__PURE__ */ r("circle", { cx: "12", cy: "10", r: "5.75", fill: i === o ? t : i }),
164
+ c >= W && /* @__PURE__ */ l(e, { children: [
165
+ /* @__PURE__ */ r(
166
+ "ellipse",
167
+ {
168
+ cx: "12",
169
+ cy: "10",
170
+ rx: "2.5",
171
+ ry: "5.1",
172
+ fill: "none",
173
+ stroke: i === o ? o : t,
174
+ strokeWidth: "1.3"
175
+ }
176
+ ),
177
+ /* @__PURE__ */ r("path", { d: "M6.25 10 H17.75", stroke: i === o ? o : t, strokeWidth: "1.3" })
178
+ ] }),
179
+ /* @__PURE__ */ r("rect", { x: "8.5", y: "17.75", width: "7", height: "1.8", rx: "0.9", fill: t })
180
+ ] })
181
+ },
182
+ // pipe (upstream "Boost Pipe"). A pipeline narrowing in three stages, the last
183
+ // -- the deal -- orange.
184
+ pipe: {
185
+ optical: 0.96,
186
+ draw: ({ accent: t }) => /* @__PURE__ */ l(e, { children: [
187
+ /* @__PURE__ */ r("rect", { x: "2.5", y: "4", width: "19", height: "4", rx: "2", fill: o }),
188
+ /* @__PURE__ */ r("rect", { x: "6", y: "10", width: "12", height: "4", rx: "2", fill: o }),
189
+ /* @__PURE__ */ r("rect", { x: "9.5", y: "16", width: "5", height: "4", rx: "2", fill: t })
190
+ ] })
191
+ }
30
192
  };
31
- function h(o) {
32
- return f.includes(o);
193
+ function k(t) {
194
+ return g.includes(t);
33
195
  }
34
- function v(o) {
35
- return h(o);
196
+ function _(t) {
197
+ return k(t);
36
198
  }
37
- function C({ slug: o, size: l = x, muted: a, title: c, className: d }) {
38
- const s = k(), e = c == null, u = h(o) ? y[o] : null;
39
- return /* @__PURE__ */ t(
199
+ function j({ slug: t, size: i = w, muted: c, title: n, className: f }) {
200
+ const x = L(), s = n == null, h = k(t) ? E[t] : null, p = c ? m : M, y = c ? o : b;
201
+ return /* @__PURE__ */ l(
40
202
  "svg",
41
203
  {
42
- className: d != null ? `${i.mark} ${d}` : i.mark,
43
- width: l,
44
- height: l,
45
- viewBox: "0 0 40 40",
46
- role: e ? void 0 : "img",
47
- "aria-hidden": e ? "true" : void 0,
48
- "aria-labelledby": e ? void 0 : s,
204
+ className: f != null ? `${a.mark} ${f}` : a.mark,
205
+ width: i,
206
+ height: i,
207
+ viewBox: `0 0 ${d} ${d}`,
208
+ role: s ? void 0 : "img",
209
+ "aria-hidden": s ? "true" : void 0,
210
+ "aria-labelledby": s ? void 0 : x,
49
211
  children: [
50
- !e && /* @__PURE__ */ r("title", { id: s, children: c }),
51
- /* @__PURE__ */ r(
52
- "rect",
53
- {
54
- className: i.ground,
55
- width: "40",
56
- height: "40",
57
- style: { fill: a ? "var(--color-neutral-300)" : "var(--color-neutral-950)" }
58
- }
59
- ),
60
- u && /* @__PURE__ */ r(
61
- "g",
62
- {
63
- transform: "translate(10 10) scale(0.5)",
64
- style: { color: "var(--color-primary-foreground)" },
65
- children: u
66
- }
67
- )
212
+ !s && /* @__PURE__ */ r("title", { id: x, children: n }),
213
+ /* @__PURE__ */ r("rect", { className: a.ground, width: d, height: d, style: { fill: p } }),
214
+ h && /* @__PURE__ */ r("g", { transform: I(h.optical), children: h.draw({ tile: p, accent: y, size: i }) })
68
215
  ]
69
216
  }
70
217
  );
71
218
  }
219
+ function I(t) {
220
+ const i = d * v * t, c = u((d - i) / 2), n = u(i / 24);
221
+ return `translate(${c} ${c}) scale(${n})`;
222
+ }
223
+ function u(t) {
224
+ return Math.round(t * 1e4) / 1e4;
225
+ }
72
226
  export {
73
- f as PRODUCT_SLUGS,
74
- C as ProductMark,
75
- v as hasProductMark
227
+ g as PRODUCT_SLUGS,
228
+ j as ProductMark,
229
+ _ as hasProductMark
76
230
  };
77
231
  //# sourceMappingURL=ProductMark.js.map