@farthershore/farthershore-js 0.1.14 → 0.1.15

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/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ This project adheres to Semantic Versioning (pre-1.0: minors may break).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.1.15] - 2026-06-10
9
+
10
+ ### Added
11
+
12
+ - **Default favicon for products without an uploaded icon.** The Root now
13
+ generates a monogram mark (the product's initial on its brand color, canvas
14
+ PNG with an SVG fallback) and applies it as the favicon when
15
+ `branding.iconUrl` is unset — instead of leaving the browser's blank
16
+ default page icon. It only ever replaces a placeholder (a missing link, the
17
+ template's `data:,`, or a previous monogram), so custom builds shipping
18
+ their own favicon are never clobbered. `<FsSplash/>` and the template's
19
+ inline boot splash show the same monogram in place of the neutral dot.
20
+ (`monogram.ts` — `productMonogramDataUri` / `applyProductFavicon`.)
21
+
8
22
  ## [0.1.14] - 2026-06-10
9
23
 
10
24
  ### Changed
@@ -0,0 +1,14 @@
1
+ /** A 64×64 letter-avatar data URI for the product (initial on brand color),
2
+ * or null when the name is empty / there is no document (SSR). */
3
+ export declare function productMonogramDataUri(name: string, brandColor?: string | null): string | null;
4
+ /** Point the document favicon at the product's mark — the uploaded icon when
5
+ * set, otherwise a generated monogram. The monogram only ever replaces a
6
+ * placeholder (a missing link, the template's `data:,`, or a previous
7
+ * monogram — tagged `data-fs-default-icon`), so a custom build shipping its
8
+ * own favicon file is never clobbered. Exported for tests. */
9
+ export declare function applyProductFavicon(doc: Document, product: {
10
+ iconUrl: string | null;
11
+ name: string;
12
+ brandColor: string | null;
13
+ }): void;
14
+ //# sourceMappingURL=monogram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monogram.d.ts","sourceRoot":"","sources":["../../src/components/monogram.ts"],"names":[],"mappings":"AA2BA;mEACmE;AACnE,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GACzB,MAAM,GAAG,IAAI,CA6Bf;AAED;;;;+DAI+D;AAC/D,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3E,IAAI,CAkCN"}
@@ -0,0 +1,98 @@
1
+ // Product monogram — the generated fallback mark for products that haven't
2
+ // uploaded an icon: the product's initial on its brand color, rendered as a
3
+ // favicon-ready data URI. Keeps no-icon portals from showing the browser's
4
+ // blank default page icon in the tab.
5
+ //
6
+ // Canvas-rendered PNG first (every browser accepts PNG data-URI favicons —
7
+ // Safari still ignores SVG favicons), with an inline-SVG data URI as the
8
+ // fallback for contexts without 2D canvas (jsdom, exotic embeds).
9
+ const DEFAULT_BRAND = "#6366f1";
10
+ function initialOf(name) {
11
+ const first = Array.from(name.trim())[0];
12
+ return first ? first.toUpperCase() : null;
13
+ }
14
+ function svgMonogram(initial, color) {
15
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">` +
16
+ `<rect width="64" height="64" rx="14" fill="${color}"/>` +
17
+ `<text x="32" y="43" font-family="system-ui,-apple-system,sans-serif" ` +
18
+ `font-size="34" font-weight="600" fill="#ffffff" text-anchor="middle">` +
19
+ `${initial.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}` +
20
+ `</text></svg>`;
21
+ return `data:image/svg+xml,${encodeURIComponent(svg)}`;
22
+ }
23
+ /** A 64×64 letter-avatar data URI for the product (initial on brand color),
24
+ * or null when the name is empty / there is no document (SSR). */
25
+ export function productMonogramDataUri(name, brandColor) {
26
+ if (typeof document === "undefined")
27
+ return null;
28
+ const initial = initialOf(name);
29
+ if (!initial)
30
+ return null;
31
+ const color = brandColor || DEFAULT_BRAND;
32
+ try {
33
+ const canvas = document.createElement("canvas");
34
+ canvas.width = 64;
35
+ canvas.height = 64;
36
+ const ctx = canvas.getContext("2d");
37
+ if (!ctx)
38
+ return svgMonogram(initial, color);
39
+ ctx.beginPath();
40
+ // Rounded square (radius 14) — matches the splash mark's shape.
41
+ if (typeof ctx.roundRect === "function") {
42
+ ctx.roundRect(0, 0, 64, 64, 14);
43
+ }
44
+ else {
45
+ ctx.rect(0, 0, 64, 64);
46
+ }
47
+ ctx.fillStyle = color;
48
+ ctx.fill();
49
+ ctx.fillStyle = "#ffffff";
50
+ ctx.font = "600 34px system-ui, -apple-system, sans-serif";
51
+ ctx.textAlign = "center";
52
+ ctx.textBaseline = "middle";
53
+ ctx.fillText(initial, 32, 34);
54
+ return canvas.toDataURL("image/png");
55
+ }
56
+ catch {
57
+ return svgMonogram(initial, color);
58
+ }
59
+ }
60
+ /** Point the document favicon at the product's mark — the uploaded icon when
61
+ * set, otherwise a generated monogram. The monogram only ever replaces a
62
+ * placeholder (a missing link, the template's `data:,`, or a previous
63
+ * monogram — tagged `data-fs-default-icon`), so a custom build shipping its
64
+ * own favicon file is never clobbered. Exported for tests. */
65
+ export function applyProductFavicon(doc, product) {
66
+ let link = doc.querySelector('link[rel="icon"]');
67
+ if (product.iconUrl) {
68
+ if (!link) {
69
+ link = doc.createElement("link");
70
+ link.rel = "icon";
71
+ doc.head.appendChild(link);
72
+ }
73
+ if (link.getAttribute("href") !== product.iconUrl) {
74
+ link.setAttribute("href", product.iconUrl);
75
+ // A type from the template's generic favicon (image/svg+xml) may not
76
+ // match the uploaded mark — drop it and let the browser sniff.
77
+ link.removeAttribute("type");
78
+ }
79
+ delete link.dataset.fsDefaultIcon;
80
+ return;
81
+ }
82
+ const raw = link?.getAttribute("href") ?? "";
83
+ const isPlaceholder = !link || raw === "" || raw === "data:," || link.dataset.fsDefaultIcon === "true";
84
+ if (!isPlaceholder)
85
+ return;
86
+ const monogram = productMonogramDataUri(product.name, product.brandColor);
87
+ if (!monogram)
88
+ return;
89
+ if (!link) {
90
+ link = doc.createElement("link");
91
+ link.rel = "icon";
92
+ doc.head.appendChild(link);
93
+ }
94
+ link.setAttribute("href", monogram);
95
+ link.removeAttribute("type");
96
+ link.dataset.fsDefaultIcon = "true";
97
+ }
98
+ //# sourceMappingURL=monogram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monogram.js","sourceRoot":"","sources":["../../src/components/monogram.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/components/root.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/D,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B;gEAC4D;IAC5D,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B;2CACuC;IACvC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,yEAAyE;IACzE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC;IAC1C,QAAQ,EAAE,SAAS,CAAC;CACrB;AAOD;gEACgE;AAChE,wBAAgB,OAAO,IAAI,SAAS,CAQnC;AAsED,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,qBAAqB,2CAM1E"}
1
+ {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/components/root.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAI/D,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B;gEAC4D;IAC5D,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B;2CACuC;IACvC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,yEAAyE;IACzE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC;IAC1C,QAAQ,EAAE,SAAS,CAAC;CACrB;AAOD;gEACgE;AAChE,wBAAgB,OAAO,IAAI,SAAS,CAQnC;AAiED,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,qBAAqB,2CAM1E"}
@@ -17,6 +17,7 @@ import { FartherShoreProvider, useBootstrap } from "../react/index.js";
17
17
  import { FsThemeProvider } from "./theme.js";
18
18
  import { FsAuthProvider } from "./auth.js";
19
19
  import { FsSplash } from "./splash.js";
20
+ import { applyProductFavicon } from "./monogram.js";
20
21
  // The resolved Bootstrap, provided by the Root's gate once resolve succeeds —
21
22
  // a single source of truth (NOT a second async read, whose state would start
22
23
  // null on a consumer's first render even with the client's promise memoized).
@@ -36,28 +37,23 @@ function DefaultSplash({ label }) {
36
37
  /** Point the document favicon at the product's square mark. The edge already
37
38
  * injects the link server-side for crawlers / pre-JS paint (site-shell
38
39
  * inject-meta); this keeps the tab icon right on hosts without the edge
39
- * injection and after client-side brand changes. */
40
- function useProductFavicon(iconUrl) {
40
+ * injection and after client-side brand changes. Products with no uploaded
41
+ * icon get a generated monogram (initial on brand color) instead of the
42
+ * browser's blank default — see monogram.ts. */
43
+ function useProductFavicon(boot) {
41
44
  useEffect(() => {
42
- if (!iconUrl || typeof document === "undefined")
45
+ if (!boot || typeof document === "undefined")
43
46
  return;
44
- let link = document.querySelector('link[rel="icon"]');
45
- if (!link) {
46
- link = document.createElement("link");
47
- link.rel = "icon";
48
- document.head.appendChild(link);
49
- }
50
- if (link.href !== iconUrl) {
51
- link.href = iconUrl;
52
- // A type from the template's generic favicon (image/svg+xml) may not
53
- // match the uploaded mark — drop it and let the browser sniff.
54
- link.removeAttribute("type");
55
- }
56
- }, [iconUrl]);
47
+ applyProductFavicon(document, {
48
+ iconUrl: boot.branding.iconUrl,
49
+ name: boot.branding.displayName,
50
+ brandColor: boot.branding.primaryColor,
51
+ });
52
+ }, [boot]);
57
53
  }
58
54
  function Gate({ appearance, clerk, splash, renderError, children, }) {
59
55
  const boot = useBootstrap();
60
- useProductFavicon(boot.data?.branding.iconUrl);
56
+ useProductFavicon(boot.data);
61
57
  // Branded mark splash — visually identical to the template's inline pre-JS
62
58
  // splash, so resolve-in-flight looks like one continuous boot.
63
59
  if (boot.loading)
@@ -1 +1 @@
1
- {"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/components/root.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/components/root.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"splash.d.ts","sourceRoot":"","sources":["../../src/components/splash.tsx"],"names":[],"mappings":"AA4CA,wEAAwE;AACxE,wBAAgB,QAAQ,4CA2BvB"}
1
+ {"version":3,"file":"splash.d.ts","sourceRoot":"","sources":["../../src/components/splash.tsx"],"names":[],"mappings":"AA4CA,wEAAwE;AACxE,wBAAgB,QAAQ,4CAgCvB"}
@@ -38,6 +38,6 @@ function readSplashContext() {
38
38
  /** Full-viewport branded splash (product mark + name, gentle pulse). */
39
39
  export function FsSplash() {
40
40
  const [{ iconUrl, name, dark }] = useState(readSplashContext);
41
- return (_jsx("div", { className: "fs-boot-splash", "data-fs-theme": dark ? "dark" : "light", style: { background: dark ? DARK_BG : LIGHT_BG }, role: "status", "aria-label": "Loading", children: _jsxs("div", { className: "fs-boot-splash__pulse", children: [iconUrl ? (_jsx("img", { className: "fs-boot-splash__mark", src: iconUrl, alt: "" })) : (_jsx("div", { className: "fs-boot-splash__dot", "aria-hidden": true })), name ? (_jsx("div", { className: "fs-boot-splash__name", style: { color: dark ? "#a1a1aa" : "#71717a" }, children: name })) : null] }) }));
41
+ return (_jsx("div", { className: "fs-boot-splash", "data-fs-theme": dark ? "dark" : "light", style: { background: dark ? DARK_BG : LIGHT_BG }, role: "status", "aria-label": "Loading", children: _jsxs("div", { className: "fs-boot-splash__pulse", children: [iconUrl ? (_jsx("img", { className: "fs-boot-splash__mark", src: iconUrl, alt: "" })) : name ? (_jsx("div", { className: "fs-boot-splash__monogram", "aria-hidden": true, children: Array.from(name.trim())[0]?.toUpperCase() ?? "" })) : (_jsx("div", { className: "fs-boot-splash__dot", "aria-hidden": true })), name ? (_jsx("div", { className: "fs-boot-splash__name", style: { color: dark ? "#a1a1aa" : "#71717a" }, children: name })) : null] }) }));
42
42
  }
43
43
  //# sourceMappingURL=splash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"splash.js","sourceRoot":"","sources":["../../src/components/splash.tsx"],"names":[],"mappings":";AAAA,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,yEAAyE;AACzE,EAAE;AACF,wEAAwE;AACxE,sCAAsC;AACtC,6EAA6E;AAC7E,wDAAwD;AACxD,mDAAmD;AACnD,6EAA6E;AAC7E,iEAAiE;AAEjE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,QAAQ,GAAG,SAAS,CAAC;AAC3B,MAAM,OAAO,GAAG,SAAS,CAAC;AAE1B,SAAS,iBAAiB;IAKxB,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAkB,kBAAkB,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC;IACpC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;IACD,MAAM,IAAI,GACR,MAAM,KAAK,MAAM;QACjB,CAAC,MAAM,KAAK,MAAM;YAChB,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;YACvC,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,QAAQ;IACtB,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC9D,OAAO,CACL,cACE,SAAS,EAAC,gBAAgB,mBACX,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EACtC,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,EAChD,IAAI,EAAC,QAAQ,gBACF,SAAS,YAEpB,eAAK,SAAS,EAAC,uBAAuB,aACnC,OAAO,CAAC,CAAC,CAAC,CACT,cAAK,SAAS,EAAC,sBAAsB,EAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAC,EAAE,GAAG,CAC9D,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,qBAAqB,wBAAe,CACpD,EACA,IAAI,CAAC,CAAC,CAAC,CACN,cACE,SAAS,EAAC,sBAAsB,EAChC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,YAE7C,IAAI,GACD,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,GACF,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"splash.js","sourceRoot":"","sources":["../../src/components/splash.tsx"],"names":[],"mappings":";AAAA,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,yEAAyE;AACzE,EAAE;AACF,wEAAwE;AACxE,sCAAsC;AACtC,6EAA6E;AAC7E,wDAAwD;AACxD,mDAAmD;AACnD,6EAA6E;AAC7E,iEAAiE;AAEjE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,QAAQ,GAAG,SAAS,CAAC;AAC3B,MAAM,OAAO,GAAG,SAAS,CAAC;AAE1B,SAAS,iBAAiB;IAKxB,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAkB,kBAAkB,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC;IACpC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;IACD,MAAM,IAAI,GACR,MAAM,KAAK,MAAM;QACjB,CAAC,MAAM,KAAK,MAAM;YAChB,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;YACvC,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,QAAQ;IACtB,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC9D,OAAO,CACL,cACE,SAAS,EAAC,gBAAgB,mBACX,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EACtC,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,EAChD,IAAI,EAAC,QAAQ,gBACF,SAAS,YAEpB,eAAK,SAAS,EAAC,uBAAuB,aACnC,OAAO,CAAC,CAAC,CAAC,CACT,cAAK,SAAS,EAAC,sBAAsB,EAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAC,EAAE,GAAG,CAC9D,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAET,cAAK,SAAS,EAAC,0BAA0B,iCACtC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,GAC5C,CACP,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,qBAAqB,wBAAe,CACpD,EACA,IAAI,CAAC,CAAC,CAAC,CACN,cACE,SAAS,EAAC,sBAAsB,EAChC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,YAE7C,IAAI,GACD,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,GACF,CACP,CAAC;AACJ,CAAC"}
@@ -702,6 +702,22 @@
702
702
  border-radius: 999px;
703
703
  background: var(--fs-color-brand, #6366f1);
704
704
  }
705
+ .fs-boot-splash__monogram {
706
+ width: 44px;
707
+ height: 44px;
708
+ border-radius: 12px;
709
+ display: grid;
710
+ place-items: center;
711
+ background: var(--fs-color-brand, #6366f1);
712
+ color: #ffffff;
713
+ font-family:
714
+ ui-sans-serif,
715
+ system-ui,
716
+ -apple-system,
717
+ sans-serif;
718
+ font-size: 20px;
719
+ font-weight: 600;
720
+ }
705
721
  .fs-boot-splash__name {
706
722
  font-size: 13px;
707
723
  font-weight: 500;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farthershore/farthershore-js",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Farther Shore Frontend SDK — the browser integration layer between static frontends and the Farther Shore platform (Core + Gateway).",
5
5
  "publishConfig": {
6
6
  "access": "public"