mentionwell 1.4.1 → 1.4.3
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 +37 -3
- package/dist/api-reader.d.ts +35 -11
- package/dist/api-reader.d.ts.map +1 -1
- package/dist/api-reader.js +40 -8
- package/dist/api-reader.js.map +1 -1
- package/dist/html-utils.d.ts +11 -2
- package/dist/html-utils.d.ts.map +1 -1
- package/dist/html-utils.js +24 -3
- package/dist/html-utils.js.map +1 -1
- package/dist/mentionwell-article.css +91 -29
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# mentionwell
|
|
2
2
|
|
|
3
|
-
Destination-side reader + styles for [Mentionwell](https://
|
|
3
|
+
Destination-side reader + styles for [Mentionwell](https://mentionwell.com)-generated blog posts. The recommended setup reads published articles from the hosted Mentionwell API with a per-site `MENTIONWELL_API_KEY`; no Supabase credentials or GitHub delivery are needed on the destination domain. The package also ships ready-to-use CSS for tables, callouts, pull quotes, FAQ accordions, citations, YouTube embeds, and a sticky table-of-contents sidebar.
|
|
4
|
+
|
|
5
|
+
## Companion packages
|
|
6
|
+
|
|
7
|
+
- [`mentionwell-cli`](https://www.npmjs.com/package/mentionwell-cli) — wires Mentionwell into your repo (`npx mentionwell-cli init`).
|
|
8
|
+
- [`mentionwell-mcp-docs`](https://www.npmjs.com/package/mentionwell-mcp-docs) — Mentionwell docs as an MCP server.
|
|
9
|
+
- [`mentionwell-mcp-account`](https://www.npmjs.com/package/mentionwell-mcp-account) — manage your Mentionwell account from any AI assistant.
|
|
4
10
|
|
|
5
11
|
## Install
|
|
6
12
|
|
|
@@ -11,7 +17,7 @@ npm install mentionwell
|
|
|
11
17
|
## Use
|
|
12
18
|
|
|
13
19
|
```ts
|
|
14
|
-
// lib/
|
|
20
|
+
// lib/mentionwell-blog.ts
|
|
15
21
|
import {
|
|
16
22
|
getBlogPostViaApi,
|
|
17
23
|
getBlogPostsViaApi,
|
|
@@ -38,7 +44,7 @@ import {
|
|
|
38
44
|
stripTocFromArticle,
|
|
39
45
|
stripPlatformChrome
|
|
40
46
|
} from 'mentionwell/html-utils'
|
|
41
|
-
import { fetchBlogPost } from '@/lib/
|
|
47
|
+
import { fetchBlogPost } from '@/lib/mentionwell-blog'
|
|
42
48
|
|
|
43
49
|
export default async function ArticlePage({ params }) {
|
|
44
50
|
const { slug } = await params
|
|
@@ -142,6 +148,34 @@ Removes the platform-rendered TL;DR, TOC, FAQ, CTA, author, header, and hero blo
|
|
|
142
148
|
|
|
143
149
|
Pull the inline `<nav class="wb-toc">` out so you can mount it in a sidebar layout.
|
|
144
150
|
|
|
151
|
+
### `getDirAttr(language)`
|
|
152
|
+
|
|
153
|
+
Returns `"rtl"` for `he-*` / `ar-*` BCP-47 codes and `"ltr"` for everything
|
|
154
|
+
else (including `undefined`). Apply it to `.wb-article-host` together with
|
|
155
|
+
`lang` — see the "RTL languages" section below.
|
|
156
|
+
|
|
157
|
+
## RTL languages
|
|
158
|
+
|
|
159
|
+
The reader supports right-to-left languages out of the box. The article
|
|
160
|
+
container emits a `dir` attribute based on the post's `language` field
|
|
161
|
+
(`he-*` and `ar-*` resolve to `rtl`). All layout uses CSS logical
|
|
162
|
+
properties, so no extra stylesheet is required.
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
import { getDirAttr } from 'mentionwell/api'
|
|
166
|
+
|
|
167
|
+
<div
|
|
168
|
+
className="wb-article-host"
|
|
169
|
+
dir={getDirAttr(post.language)}
|
|
170
|
+
lang={post.language}
|
|
171
|
+
dangerouslySetInnerHTML={{ __html: bodyHtml }}
|
|
172
|
+
/>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
If you self-host fonts, add Hebrew (Heebo/Assistant/Rubik) or Arabic
|
|
176
|
+
(Noto Naskh Arabic/Cairo/Tajawal) webfonts to your destination site. The
|
|
177
|
+
reader's CSS variables fall back to system fonts gracefully.
|
|
178
|
+
|
|
145
179
|
## License
|
|
146
180
|
|
|
147
181
|
MIT
|
package/dist/api-reader.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* API-mode reader for
|
|
2
|
+
* API-mode reader for Mentionwell.
|
|
3
3
|
*
|
|
4
|
-
* Talks to a hosted
|
|
4
|
+
* Talks to a hosted Mentionwell instance over HTTPS instead of going directly to
|
|
5
5
|
* Supabase. This is the recommended mode when you don't want destination
|
|
6
6
|
* sites to know about your Supabase URL/anon key.
|
|
7
7
|
*
|
|
8
|
-
* Endpoints (provided by
|
|
8
|
+
* Endpoints (provided by Mentionwell `app/api/public/[siteSlug]/...`):
|
|
9
9
|
* GET /api/public/{siteSlug}/posts?limit=100 → list
|
|
10
10
|
* GET /api/public/{siteSlug}/posts/{slug} → detail
|
|
11
11
|
*
|
|
12
12
|
* Auth: `Authorization: Bearer <apiKey>` where apiKey is the per-site key
|
|
13
|
-
* surfaced in the
|
|
14
|
-
* derived from siteId + READER_API_SECRET, prefix `
|
|
13
|
+
* surfaced in the Mentionwell dashboard's integration page (deterministically
|
|
14
|
+
* derived from siteId + READER_API_SECRET, prefix `mw_read_`).
|
|
15
15
|
*/
|
|
16
16
|
export interface ReaderAuthor {
|
|
17
17
|
id: string;
|
|
@@ -65,11 +65,35 @@ export interface ReaderPost {
|
|
|
65
65
|
jsonLd: string;
|
|
66
66
|
};
|
|
67
67
|
canonicalUrl?: string;
|
|
68
|
+
/**
|
|
69
|
+
* BCP-47 language tag for the post (e.g. `"en-US"`, `"he-IL"`, `"ar-SA"`).
|
|
70
|
+
* Drives both the `lang` attribute and direction (`dir`) of the article
|
|
71
|
+
* host element. Use {@link getDirAttr} to derive the `dir` value.
|
|
72
|
+
*/
|
|
73
|
+
language?: string;
|
|
68
74
|
}
|
|
69
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Returns the writing direction for a given BCP-47 language tag.
|
|
77
|
+
*
|
|
78
|
+
* Hebrew (`he*`) and Arabic (`ar*`) resolve to `"rtl"`; everything else
|
|
79
|
+
* (including unknown / missing values) returns `"ltr"`. Apply this to the
|
|
80
|
+
* `.wb-article-host` element so the bundled stylesheet — which is built
|
|
81
|
+
* entirely on CSS logical properties — flips the layout automatically:
|
|
82
|
+
*
|
|
83
|
+
* ```tsx
|
|
84
|
+
* <div
|
|
85
|
+
* className="wb-article-host"
|
|
86
|
+
* dir={getDirAttr(post.language)}
|
|
87
|
+
* lang={post.language}
|
|
88
|
+
* dangerouslySetInnerHTML={{ __html: html }}
|
|
89
|
+
* />
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare function getDirAttr(language: string | undefined): "rtl" | "ltr";
|
|
93
|
+
export interface MentionwellApiConfig {
|
|
70
94
|
/** Base URL of the Mentionwell instance, e.g. https://app.mentionwell.com */
|
|
71
95
|
apiUrl: string;
|
|
72
|
-
/** Per-site API key (Bearer token), prefix `
|
|
96
|
+
/** Per-site API key (Bearer token), prefix `mw_read_`. */
|
|
73
97
|
apiKey: string;
|
|
74
98
|
/** Slug of this destination site as registered in Mentionwell. */
|
|
75
99
|
siteSlug: string;
|
|
@@ -86,14 +110,14 @@ export interface BlogotoApiConfig {
|
|
|
86
110
|
* which silently hid every page past the first. Sites with >100 posts
|
|
87
111
|
* need server-side `?page=` support; bump this package once that lands.
|
|
88
112
|
*/
|
|
89
|
-
export declare function getBlogPostsViaApi(config:
|
|
113
|
+
export declare function getBlogPostsViaApi(config: MentionwellApiConfig, page?: number, perPage?: number): Promise<{
|
|
90
114
|
posts: ReaderPost[];
|
|
91
115
|
total: number;
|
|
92
116
|
totalPages: number;
|
|
93
117
|
}>;
|
|
94
|
-
export declare function getBlogPostViaApi(config:
|
|
95
|
-
export declare function getAllBlogSlugsViaApi(config:
|
|
96
|
-
export declare function getBlogPostSummariesViaApi(config:
|
|
118
|
+
export declare function getBlogPostViaApi(config: MentionwellApiConfig, slug: string): Promise<ReaderPost | null>;
|
|
119
|
+
export declare function getAllBlogSlugsViaApi(config: MentionwellApiConfig): Promise<string[]>;
|
|
120
|
+
export declare function getBlogPostSummariesViaApi(config: MentionwellApiConfig): Promise<Array<{
|
|
97
121
|
slug: string;
|
|
98
122
|
updatedAt?: string;
|
|
99
123
|
publishedAt?: string;
|
package/dist/api-reader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-reader.d.ts","sourceRoot":"","sources":["../src/api-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,YAAY,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC3B,GAAG,CAAC,EAAE,cAAc,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"api-reader.d.ts","sourceRoot":"","sources":["../src/api-reader.ts"],"names":[],"mappings":"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"}
|
package/dist/api-reader.js
CHANGED
|
@@ -1,18 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* API-mode reader for
|
|
2
|
+
* API-mode reader for Mentionwell.
|
|
3
3
|
*
|
|
4
|
-
* Talks to a hosted
|
|
4
|
+
* Talks to a hosted Mentionwell instance over HTTPS instead of going directly to
|
|
5
5
|
* Supabase. This is the recommended mode when you don't want destination
|
|
6
6
|
* sites to know about your Supabase URL/anon key.
|
|
7
7
|
*
|
|
8
|
-
* Endpoints (provided by
|
|
8
|
+
* Endpoints (provided by Mentionwell `app/api/public/[siteSlug]/...`):
|
|
9
9
|
* GET /api/public/{siteSlug}/posts?limit=100 → list
|
|
10
10
|
* GET /api/public/{siteSlug}/posts/{slug} → detail
|
|
11
11
|
*
|
|
12
12
|
* Auth: `Authorization: Bearer <apiKey>` where apiKey is the per-site key
|
|
13
|
-
* surfaced in the
|
|
14
|
-
* derived from siteId + READER_API_SECRET, prefix `
|
|
13
|
+
* surfaced in the Mentionwell dashboard's integration page (deterministically
|
|
14
|
+
* derived from siteId + READER_API_SECRET, prefix `mw_read_`).
|
|
15
15
|
*/
|
|
16
|
+
/**
|
|
17
|
+
* Returns the writing direction for a given BCP-47 language tag.
|
|
18
|
+
*
|
|
19
|
+
* Hebrew (`he*`) and Arabic (`ar*`) resolve to `"rtl"`; everything else
|
|
20
|
+
* (including unknown / missing values) returns `"ltr"`. Apply this to the
|
|
21
|
+
* `.wb-article-host` element so the bundled stylesheet — which is built
|
|
22
|
+
* entirely on CSS logical properties — flips the layout automatically:
|
|
23
|
+
*
|
|
24
|
+
* ```tsx
|
|
25
|
+
* <div
|
|
26
|
+
* className="wb-article-host"
|
|
27
|
+
* dir={getDirAttr(post.language)}
|
|
28
|
+
* lang={post.language}
|
|
29
|
+
* dangerouslySetInnerHTML={{ __html: html }}
|
|
30
|
+
* />
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function getDirAttr(language) {
|
|
34
|
+
if (!language)
|
|
35
|
+
return "ltr";
|
|
36
|
+
const code = language.toLowerCase();
|
|
37
|
+
if (code.startsWith("he") || code.startsWith("ar"))
|
|
38
|
+
return "rtl";
|
|
39
|
+
return "ltr";
|
|
40
|
+
}
|
|
16
41
|
function trimUrl(url) {
|
|
17
42
|
return url.replace(/\/+$/, "");
|
|
18
43
|
}
|
|
@@ -28,7 +53,13 @@ function toReader(post) {
|
|
|
28
53
|
excerpt: post.excerpt ?? "",
|
|
29
54
|
html: post.html ?? "",
|
|
30
55
|
markdown: post.markdown,
|
|
31
|
-
|
|
56
|
+
// Treat the legacy "/placeholder.jpg" sentinel as missing — destination
|
|
57
|
+
// sites resolve relative URLs against their own domain, so it 404s on
|
|
58
|
+
// every client that doesn't host that exact file. Returning undefined
|
|
59
|
+
// lets templates skip the hero figure cleanly.
|
|
60
|
+
featuredImage: post.featuredImage && post.featuredImage !== "/placeholder.jpg"
|
|
61
|
+
? post.featuredImage
|
|
62
|
+
: undefined,
|
|
32
63
|
readingTime: post.readingTime,
|
|
33
64
|
tags: post.tags ?? [],
|
|
34
65
|
category: post.category ?? null,
|
|
@@ -40,7 +71,8 @@ function toReader(post) {
|
|
|
40
71
|
toc: post.toc ?? undefined,
|
|
41
72
|
faqs: post.faqs ?? undefined,
|
|
42
73
|
schema: post.jsonLd ? { jsonLd: post.jsonLd } : undefined,
|
|
43
|
-
canonicalUrl: post.canonicalUrl ?? undefined
|
|
74
|
+
canonicalUrl: post.canonicalUrl ?? undefined,
|
|
75
|
+
language: post.language ?? undefined
|
|
44
76
|
};
|
|
45
77
|
}
|
|
46
78
|
async function callApi(config, path, init) {
|
|
@@ -64,7 +96,7 @@ async function callApi(config, path, init) {
|
|
|
64
96
|
catch {
|
|
65
97
|
// body wasn't JSON; keep status text
|
|
66
98
|
}
|
|
67
|
-
throw new Error(`
|
|
99
|
+
throw new Error(`Mentionwell API ${path} failed: ${message}`);
|
|
68
100
|
}
|
|
69
101
|
return (await response.json());
|
|
70
102
|
}
|
package/dist/api-reader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-reader.js","sourceRoot":"","sources":["../src/api-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"api-reader.js","sourceRoot":"","sources":["../src/api-reader.ts"],"names":[],"mappings":"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"}
|
package/dist/html-utils.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Helpers for rendering
|
|
2
|
+
* Helpers for rendering Mentionwell-generated article HTML on a destination site.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Mentionwell's `buildArticleHtml` produces a self-contained article with a
|
|
5
5
|
* `<header class="wb-header">` (title + dek + tags) and a
|
|
6
6
|
* `<figure class="wb-hero">` (cover image). Most destination templates also
|
|
7
7
|
* render their own hero/title/cover, so injecting `post.html` raw double-
|
|
@@ -17,6 +17,15 @@
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function stripDuplicateChrome(html: string): string;
|
|
19
19
|
export declare function stripLegacyCtaLeaks(html: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Older Mentionwell renders emitted callouts without a leading
|
|
22
|
+
* `<span class="wb-callout-emoji">…</span>` element. Most destination CSS
|
|
23
|
+
* templates lay the callout out as a 2-column grid (icon + body), so missing
|
|
24
|
+
* the icon span pushes the body into the narrow icon column and collapses
|
|
25
|
+
* the text to one word per line. Inject the missing emoji at read time so
|
|
26
|
+
* existing posts render correctly without re-publishing every article.
|
|
27
|
+
*/
|
|
28
|
+
export declare function repairLegacyCallouts(html: string): string;
|
|
20
29
|
export declare function extractTocHtml(html: string): string | null;
|
|
21
30
|
export declare function stripTocFromArticle(html: string): string;
|
|
22
31
|
export declare function stripPlatformChrome(html: string): string;
|
package/dist/html-utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-utils.d.ts","sourceRoot":"","sources":["../src/html-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG1D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,yBAA8B,GAAG,MAAM,CAKhG"}
|
|
1
|
+
{"version":3,"file":"html-utils.d.ts","sourceRoot":"","sources":["../src/html-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAezD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG1D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,yBAA8B,GAAG,MAAM,CAKhG"}
|
package/dist/html-utils.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Helpers for rendering
|
|
2
|
+
* Helpers for rendering Mentionwell-generated article HTML on a destination site.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Mentionwell's `buildArticleHtml` produces a self-contained article with a
|
|
5
5
|
* `<header class="wb-header">` (title + dek + tags) and a
|
|
6
6
|
* `<figure class="wb-hero">` (cover image). Most destination templates also
|
|
7
7
|
* render their own hero/title/cover, so injecting `post.html` raw double-
|
|
@@ -27,6 +27,27 @@ export function stripLegacyCtaLeaks(html) {
|
|
|
27
27
|
.replace(/<strong>\s*\[CTA\]\s*<\/strong>/g, "")
|
|
28
28
|
.replace(/\[CTA\]/g, "");
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Older Mentionwell renders emitted callouts without a leading
|
|
32
|
+
* `<span class="wb-callout-emoji">…</span>` element. Most destination CSS
|
|
33
|
+
* templates lay the callout out as a 2-column grid (icon + body), so missing
|
|
34
|
+
* the icon span pushes the body into the narrow icon column and collapses
|
|
35
|
+
* the text to one word per line. Inject the missing emoji at read time so
|
|
36
|
+
* existing posts render correctly without re-publishing every article.
|
|
37
|
+
*/
|
|
38
|
+
export function repairLegacyCallouts(html) {
|
|
39
|
+
const emojiByVariant = {
|
|
40
|
+
tip: "💡",
|
|
41
|
+
warning: "⚠️",
|
|
42
|
+
stat: "📊"
|
|
43
|
+
};
|
|
44
|
+
return html.replace(/<aside\b([^>]*\bclass="[^"]*\bwb-callout\b[^"]*"[^>]*)>(\s*)(?!<span[^>]*\bwb-callout-emoji\b)/gi, (match, attrs, gap) => {
|
|
45
|
+
const variantMatch = attrs.match(/wb-callout-(tip|warning|stat)\b/i);
|
|
46
|
+
const variant = variantMatch ? variantMatch[1].toLowerCase() : "tip";
|
|
47
|
+
const emoji = emojiByVariant[variant] ?? "💡";
|
|
48
|
+
return `<aside${attrs}>${gap}<span class="wb-callout-emoji" aria-hidden="true">${emoji}</span>`;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
30
51
|
export function extractTocHtml(html) {
|
|
31
52
|
const match = html.match(/<nav class="wb-toc"[\s\S]*?<\/nav>/);
|
|
32
53
|
return match ? match[0] : null;
|
|
@@ -44,7 +65,7 @@ export function stripPlatformChrome(html) {
|
|
|
44
65
|
}
|
|
45
66
|
/** Convenience: apply all the safe transforms in one call. */
|
|
46
67
|
export function prepareArticleHtml(html, options = {}) {
|
|
47
|
-
let next = stripLegacyCtaLeaks(stripDuplicateChrome(html));
|
|
68
|
+
let next = repairLegacyCallouts(stripLegacyCtaLeaks(stripDuplicateChrome(html)));
|
|
48
69
|
if (options.stripPlatformChrome)
|
|
49
70
|
next = stripPlatformChrome(next);
|
|
50
71
|
if (options.stripToc)
|
package/dist/html-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-utils.js","sourceRoot":"","sources":["../src/html-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI;SACR,OAAO,CAAC,8CAA8C,EAAE,EAAE,CAAC;SAC3D,OAAO,CAAC,4CAA4C,EAAE,EAAE,CAAC;SACzD,OAAO,CAAC,gDAAgD,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI;SACR,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC;SACtE,OAAO,CAAC,kCAAkC,EAAE,EAAE,CAAC;SAC/C,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,oBAAoB,CAAC,IAAI,CAAC;SAC9B,OAAO,CAAC,qEAAqE,EAAE,EAAE,CAAC;SAClF,OAAO,CAAC,wEAAwE,EAAE,EAAE,CAAC;SACrF,OAAO,CAAC,mFAAmF,EAAE,EAAE,CAAC;SAChG,OAAO,CAAC,uEAAuE,EAAE,EAAE,CAAC;SACpF,OAAO,CAAC,gEAAgE,EAAE,EAAE,CAAC,CAAC;AACnF,CAAC;AAaD,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,UAAqC,EAAE;IACtF,IAAI,IAAI,GAAG,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"html-utils.js","sourceRoot":"","sources":["../src/html-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI;SACR,OAAO,CAAC,8CAA8C,EAAE,EAAE,CAAC;SAC3D,OAAO,CAAC,4CAA4C,EAAE,EAAE,CAAC;SACzD,OAAO,CAAC,gDAAgD,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI;SACR,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC;SACtE,OAAO,CAAC,kCAAkC,EAAE,EAAE,CAAC;SAC/C,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,cAAc,GAA2B;QAC7C,GAAG,EAAE,IAAI;QACT,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,IAAI;KACX,CAAC;IACF,OAAO,IAAI,CAAC,OAAO,CACjB,kGAAkG,EAClG,CAAC,KAAK,EAAE,KAAa,EAAE,GAAW,EAAE,EAAE;QACpC,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QACrE,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;QAC9C,OAAO,SAAS,KAAK,IAAI,GAAG,qDAAqD,KAAK,SAAS,CAAC;IAClG,CAAC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,oBAAoB,CAAC,IAAI,CAAC;SAC9B,OAAO,CAAC,qEAAqE,EAAE,EAAE,CAAC;SAClF,OAAO,CAAC,wEAAwE,EAAE,EAAE,CAAC;SACrF,OAAO,CAAC,mFAAmF,EAAE,EAAE,CAAC;SAChG,OAAO,CAAC,uEAAuE,EAAE,EAAE,CAAC;SACpF,OAAO,CAAC,gEAAgE,EAAE,EAAE,CAAC,CAAC;AACnF,CAAC;AAaD,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,UAAqC,EAAE;IACtF,IAAI,IAAI,GAAG,oBAAoB,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjF,IAAI,OAAO,CAAC,mBAAmB;QAAE,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,OAAO,CAAC,QAAQ;QAAE,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/* ============================================================
|
|
2
2
|
@isaac/blog-reader/styles
|
|
3
|
-
Default styles for
|
|
3
|
+
Default styles for Mentionwell-generated article HTML (wb-* class
|
|
4
4
|
namespace produced by lib/blog/article-html.ts).
|
|
5
5
|
|
|
6
6
|
All colors, fonts, and radii are CSS variables prefixed with
|
|
7
7
|
--wb-*. Override them in your destination site to re-theme.
|
|
8
8
|
Defaults below match a warm, editorial palette.
|
|
9
|
+
|
|
10
|
+
Layout uses CSS logical properties (margin-inline-*, padding-inline-*,
|
|
11
|
+
border-inline-*, inset-inline-*, text-align: start/end, float:
|
|
12
|
+
inline-start/end) so setting `dir="rtl"` on `.wb-article-host`
|
|
13
|
+
flips the entire layout for Hebrew/Arabic with no extra rules.
|
|
9
14
|
============================================================ */
|
|
10
15
|
|
|
11
16
|
:root {
|
|
@@ -54,7 +59,7 @@
|
|
|
54
59
|
.wb-article-host ul,
|
|
55
60
|
.wb-article-host ol {
|
|
56
61
|
margin: 1rem 0 1.5rem;
|
|
57
|
-
padding-
|
|
62
|
+
padding-inline-start: 1.5rem;
|
|
58
63
|
}
|
|
59
64
|
.wb-article-host ul:not(.wb-steps) li,
|
|
60
65
|
.wb-article-host ol:not(.wb-steps) li {
|
|
@@ -135,7 +140,7 @@
|
|
|
135
140
|
.wb-article-host li a[rel*="noopener"][target="_blank"]::after {
|
|
136
141
|
content: "↗";
|
|
137
142
|
font-size: 0.85em;
|
|
138
|
-
margin-
|
|
143
|
+
margin-inline-start: 0.15em;
|
|
139
144
|
color: var(--wb-bronze);
|
|
140
145
|
}
|
|
141
146
|
|
|
@@ -153,7 +158,7 @@
|
|
|
153
158
|
.wb-article-host li a:has(> sup:only-child)::after,
|
|
154
159
|
.wb-article-host td a:has(> sup:only-child)::after {
|
|
155
160
|
font-size: 0.65em;
|
|
156
|
-
margin-
|
|
161
|
+
margin-inline-start: 0.05em;
|
|
157
162
|
opacity: 0.7;
|
|
158
163
|
}
|
|
159
164
|
.wb-article-host sup {
|
|
@@ -190,7 +195,7 @@
|
|
|
190
195
|
.wb-article-host .wb-related li::before {
|
|
191
196
|
content: "→";
|
|
192
197
|
color: var(--wb-bronze);
|
|
193
|
-
margin-
|
|
198
|
+
margin-inline-end: 0.5rem;
|
|
194
199
|
font-weight: 600;
|
|
195
200
|
}
|
|
196
201
|
.wb-article-host .wb-related a {
|
|
@@ -251,7 +256,7 @@
|
|
|
251
256
|
.wb-article-host .wb-tldr {
|
|
252
257
|
border: 1px solid #D6CFC4;
|
|
253
258
|
background: #F6F2EB;
|
|
254
|
-
border-
|
|
259
|
+
border-inline-start: 4px solid #9A7453;
|
|
255
260
|
border-radius: 12px;
|
|
256
261
|
padding: 1.25rem 1.5rem;
|
|
257
262
|
margin: 0 0 2.5rem;
|
|
@@ -269,13 +274,13 @@
|
|
|
269
274
|
/* --- TOC sidebar ------------------------------------------ */
|
|
270
275
|
.wb-toc-sidebar .wb-toc {
|
|
271
276
|
background: transparent; padding: 0; border: 0;
|
|
272
|
-
border-
|
|
277
|
+
border-inline-start: 1px solid var(--wb-border); margin: 0;
|
|
273
278
|
}
|
|
274
279
|
.wb-toc-sidebar .wb-toc h2 {
|
|
275
280
|
font-family: var(--wb-font-display);
|
|
276
281
|
font-size: 0.7rem; font-weight: 600;
|
|
277
282
|
text-transform: uppercase; letter-spacing: 0.12em;
|
|
278
|
-
color: var(--wb-body); margin: 0 0 0.75rem; padding-
|
|
283
|
+
color: var(--wb-body); margin: 0 0 0.75rem; padding-inline-start: 1rem;
|
|
279
284
|
}
|
|
280
285
|
.wb-toc-sidebar .wb-toc ul, .wb-toc-sidebar .wb-toc ol {
|
|
281
286
|
margin: 0; padding: 0; list-style: none;
|
|
@@ -286,15 +291,15 @@
|
|
|
286
291
|
color: var(--wb-body); text-decoration: none;
|
|
287
292
|
font-family: var(--wb-font-body);
|
|
288
293
|
font-size: 0.9rem; line-height: 1.4;
|
|
289
|
-
border-
|
|
294
|
+
border-inline-start: 2px solid transparent; margin-inline-start: -1px;
|
|
290
295
|
transition: color 150ms ease, border-color 150ms ease;
|
|
291
296
|
}
|
|
292
297
|
.wb-toc-sidebar .wb-toc a:hover {
|
|
293
|
-
color: var(--wb-ink); border-
|
|
298
|
+
color: var(--wb-ink); border-inline-start-color: var(--wb-bronze);
|
|
294
299
|
}
|
|
295
300
|
|
|
296
301
|
/* --- Section headers --------------------------------------- */
|
|
297
|
-
/* Cover both
|
|
302
|
+
/* Cover both Mentionwell-generated structure (section.wb-section > h2) AND
|
|
298
303
|
plain h2/h3s from migrated/legacy content. */
|
|
299
304
|
.wb-article-host section.wb-section { margin-top: 3rem; }
|
|
300
305
|
.wb-article-host section.wb-section > h2,
|
|
@@ -346,7 +351,7 @@
|
|
|
346
351
|
margin-top: 0.5rem; font-size: 0.85rem;
|
|
347
352
|
color: var(--wb-body); font-style: italic; text-align: center;
|
|
348
353
|
}
|
|
349
|
-
.wb-article-host .wb-infographic { max-width: 720px; margin-
|
|
354
|
+
.wb-article-host .wb-infographic { max-width: 720px; margin-inline-start: auto; margin-inline-end: auto; }
|
|
350
355
|
|
|
351
356
|
/* --- YouTube card ------------------------------------------ */
|
|
352
357
|
.wb-article-host .wb-youtube { margin: 2.5rem 0; max-width: 100%; }
|
|
@@ -403,6 +408,9 @@
|
|
|
403
408
|
}
|
|
404
409
|
.wb-article-host .wb-faq-item > summary::-webkit-details-marker { display: none; }
|
|
405
410
|
.wb-article-host .wb-faq-item > summary::before {
|
|
411
|
+
/* physical: intentional — chevron is a rotated square; rotation math
|
|
412
|
+
is direction-agnostic and the closed/open transform is purely
|
|
413
|
+
visual, not a directional cue. */
|
|
406
414
|
content: ''; flex: none; width: 10px; height: 10px;
|
|
407
415
|
border-right: 2px solid var(--wb-bronze-deep);
|
|
408
416
|
border-bottom: 2px solid var(--wb-bronze-deep);
|
|
@@ -415,7 +423,12 @@
|
|
|
415
423
|
color: var(--wb-ink); line-height: 1.4;
|
|
416
424
|
}
|
|
417
425
|
.wb-article-host .wb-faq-answer {
|
|
418
|
-
padding: 0 1.25rem
|
|
426
|
+
padding-block: 0 1.25rem;
|
|
427
|
+
padding-inline: 1.25rem 2.75rem;
|
|
428
|
+
/* Note: the larger inset is on the inline-end side to clear the chevron
|
|
429
|
+
that lives at the inline-start of the summary. In RTL, summary content
|
|
430
|
+
reverses so the chevron sits at inline-start (the visual right) and the
|
|
431
|
+
larger inset still lands away from it. */
|
|
419
432
|
color: #3A3732; line-height: 1.65;
|
|
420
433
|
}
|
|
421
434
|
.wb-article-host .wb-faq-answer p { margin: 0.5rem 0; }
|
|
@@ -472,19 +485,26 @@
|
|
|
472
485
|
under a sticky sidebar CTA). `display: block` is what makes overflow-x
|
|
473
486
|
actually work — `display: table` ignores `overflow` on itself. */
|
|
474
487
|
.wb-article-host table {
|
|
475
|
-
|
|
488
|
+
/* Real table layout so cells stretch to fill the container width.
|
|
489
|
+
`display: block` (the previous attempt at making the table scroll
|
|
490
|
+
horizontally) caused the inner table layout to collapse to its
|
|
491
|
+
content width, leaving a large empty band on the right side of the
|
|
492
|
+
bordered region. We rely on `table-layout: auto` + `width: 100%`
|
|
493
|
+
so columns fill the article column instead. Mobile horizontal
|
|
494
|
+
scroll is handled below by giving the table its own scroll wrapper
|
|
495
|
+
via the `display` switch only at narrow breakpoints. */
|
|
496
|
+
display: table;
|
|
476
497
|
width: 100%;
|
|
477
498
|
max-width: 100%;
|
|
478
|
-
|
|
479
|
-
-webkit-overflow-scrolling: touch;
|
|
499
|
+
table-layout: auto;
|
|
480
500
|
border-collapse: collapse;
|
|
481
501
|
margin: 2rem 0;
|
|
482
502
|
font-size: 0.95rem;
|
|
483
503
|
background: var(--wb-paper);
|
|
484
|
-
/* Stronger border so the table is visible against paper-tone page bgs. */
|
|
485
504
|
border: 1px solid #B7AEA1;
|
|
486
505
|
border-radius: var(--wb-radius-sm);
|
|
487
506
|
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.03);
|
|
507
|
+
overflow: hidden;
|
|
488
508
|
}
|
|
489
509
|
/* Forest-green header with cream text. !important guards defeat host
|
|
490
510
|
themes that set a generic cream/light bg on `.blog-content th` and
|
|
@@ -498,7 +518,7 @@
|
|
|
498
518
|
.wb-article-host thead th {
|
|
499
519
|
background: #3C5445 !important;
|
|
500
520
|
color: #FAF7F2 !important;
|
|
501
|
-
text-align:
|
|
521
|
+
text-align: start;
|
|
502
522
|
font-family: var(--wb-font-display);
|
|
503
523
|
font-weight: 600;
|
|
504
524
|
font-size: 0.78rem;
|
|
@@ -517,12 +537,19 @@
|
|
|
517
537
|
.wb-article-host tbody tr:nth-child(even) { background: var(--wb-cream); }
|
|
518
538
|
.wb-article-host tbody tr:hover { background: #F0EBE1; }
|
|
519
539
|
.wb-article-host th + th,
|
|
520
|
-
.wb-article-host td + td { border-
|
|
540
|
+
.wb-article-host td + td { border-inline-start: 1px solid #E2DBCE; }
|
|
521
541
|
|
|
522
542
|
/* Mobile: tighten table cells. (Horizontal scroll is already enabled at
|
|
523
543
|
all breakpoints in the base table rule above.) */
|
|
524
544
|
@media (max-width: 640px) {
|
|
545
|
+
/* On narrow screens, allow the table to scroll horizontally inside the
|
|
546
|
+
article column rather than overflowing the page. `display: block` here
|
|
547
|
+
lets `overflow-x: auto` actually take effect (which it can't on a
|
|
548
|
+
`display: table` element). */
|
|
525
549
|
.wb-article-host table {
|
|
550
|
+
display: block;
|
|
551
|
+
overflow-x: auto;
|
|
552
|
+
-webkit-overflow-scrolling: touch;
|
|
526
553
|
font-size: 0.88rem;
|
|
527
554
|
}
|
|
528
555
|
.wb-article-host thead th, .wb-article-host tbody td {
|
|
@@ -534,6 +561,8 @@
|
|
|
534
561
|
.wb-article-host hr.wb-divider {
|
|
535
562
|
border: 0;
|
|
536
563
|
height: 1px;
|
|
564
|
+
/* physical: intentional — the linear-gradient direction here is a
|
|
565
|
+
visual fade that reads identically in both LTR and RTL. */
|
|
537
566
|
background: linear-gradient(to right, transparent, var(--wb-border) 20%, var(--wb-border) 80%, transparent);
|
|
538
567
|
margin: 2.5rem auto;
|
|
539
568
|
max-width: 60%;
|
|
@@ -541,8 +570,10 @@
|
|
|
541
570
|
|
|
542
571
|
/* --- Pull quote ------------------------------------------- */
|
|
543
572
|
.wb-article-host blockquote.wb-quote, .wb-article-host blockquote {
|
|
544
|
-
margin: 2rem 0;
|
|
545
|
-
|
|
573
|
+
margin: 2rem 0;
|
|
574
|
+
padding-block: 0.5rem;
|
|
575
|
+
padding-inline-start: 1.5rem;
|
|
576
|
+
border-inline-start: 3px solid var(--wb-bronze);
|
|
546
577
|
font-family: var(--wb-font-display); font-weight: 500;
|
|
547
578
|
font-size: 1.2rem; line-height: 1.5;
|
|
548
579
|
color: var(--wb-ink); font-style: normal;
|
|
@@ -560,7 +591,7 @@
|
|
|
560
591
|
margin: 2rem 0;
|
|
561
592
|
border-radius: var(--wb-radius-md);
|
|
562
593
|
border: 1px solid;
|
|
563
|
-
border-
|
|
594
|
+
border-inline-start-width: 4px;
|
|
564
595
|
font-size: 0.97rem;
|
|
565
596
|
line-height: 1.6;
|
|
566
597
|
}
|
|
@@ -584,7 +615,7 @@
|
|
|
584
615
|
.wb-article-host .wb-callout-tip {
|
|
585
616
|
background: linear-gradient(180deg, #F2F7F0 0%, #ECF3E9 100%);
|
|
586
617
|
border-color: #C2D0BD;
|
|
587
|
-
border-
|
|
618
|
+
border-inline-start-color: var(--wb-forest);
|
|
588
619
|
color: #1F3324;
|
|
589
620
|
}
|
|
590
621
|
.wb-article-host .wb-callout-tip .wb-callout-label { color: var(--wb-forest); }
|
|
@@ -592,7 +623,7 @@
|
|
|
592
623
|
.wb-article-host .wb-callout-warning {
|
|
593
624
|
background: linear-gradient(180deg, #FCF3E5 0%, #F8EAD4 100%);
|
|
594
625
|
border-color: #E5C7A0;
|
|
595
|
-
border-
|
|
626
|
+
border-inline-start-color: #C58A2D;
|
|
596
627
|
color: #4A3618;
|
|
597
628
|
}
|
|
598
629
|
.wb-article-host .wb-callout-warning .wb-callout-label { color: #9A6E2D; }
|
|
@@ -600,7 +631,7 @@
|
|
|
600
631
|
.wb-article-host .wb-callout-stat {
|
|
601
632
|
background: linear-gradient(180deg, #F2EFF9 0%, #ECE7F5 100%);
|
|
602
633
|
border-color: #C7BFD9;
|
|
603
|
-
border-
|
|
634
|
+
border-inline-start-color: #6C5BA1;
|
|
604
635
|
color: #2C2447;
|
|
605
636
|
}
|
|
606
637
|
.wb-article-host .wb-callout-stat .wb-callout-label { color: #5C4F8A; }
|
|
@@ -613,13 +644,14 @@
|
|
|
613
644
|
}
|
|
614
645
|
.wb-article-host ol.wb-steps > li {
|
|
615
646
|
counter-increment: wb-step; position: relative;
|
|
616
|
-
padding: 0.85rem
|
|
647
|
+
padding-block: 0.85rem;
|
|
648
|
+
padding-inline: 3rem 1rem;
|
|
617
649
|
background: var(--wb-paper); border: 1px solid var(--wb-border);
|
|
618
650
|
border-radius: var(--wb-radius-sm); line-height: 1.55; color: #3A3732;
|
|
619
651
|
}
|
|
620
652
|
.wb-article-host ol.wb-steps > li::before {
|
|
621
653
|
content: counter(wb-step);
|
|
622
|
-
position: absolute;
|
|
654
|
+
position: absolute; inset-inline-start: 0.85rem; top: 0.7rem;
|
|
623
655
|
width: 1.6rem; height: 1.6rem;
|
|
624
656
|
border-radius: 999px;
|
|
625
657
|
background: var(--wb-forest); color: #FAF7F2;
|
|
@@ -648,7 +680,7 @@
|
|
|
648
680
|
.wb-article-host .wb-citation-index {
|
|
649
681
|
flex: none; font-family: var(--wb-font-display); font-weight: 600;
|
|
650
682
|
font-size: 0.85rem; color: var(--wb-bronze-deep);
|
|
651
|
-
min-width: 1.25rem; text-align:
|
|
683
|
+
min-width: 1.25rem; text-align: end;
|
|
652
684
|
}
|
|
653
685
|
.wb-article-host .wb-citation-body {
|
|
654
686
|
display: flex; flex-direction: column; gap: 0.15rem; min-width: 0;
|
|
@@ -768,7 +800,7 @@
|
|
|
768
800
|
.wb-sticky-toc {
|
|
769
801
|
position: sticky; top: var(--wb-sticky-top, 6rem); align-self: start;
|
|
770
802
|
max-height: calc(100vh - 8rem); overflow-y: auto;
|
|
771
|
-
padding-
|
|
803
|
+
padding-inline-end: 0.5rem;
|
|
772
804
|
z-index: 1;
|
|
773
805
|
}
|
|
774
806
|
@media (max-width: 1023px) { .wb-sticky-toc { display: none; } }
|
|
@@ -877,3 +909,33 @@
|
|
|
877
909
|
background: #3C5445 !important;
|
|
878
910
|
color: #FAF7F2 !important;
|
|
879
911
|
}
|
|
912
|
+
|
|
913
|
+
/* ============================================================
|
|
914
|
+
Hebrew / Arabic typography presets.
|
|
915
|
+
Activated by [dir="rtl"][lang^="he"] (or [lang^="ar"]) on the host.
|
|
916
|
+
Use webfonts the destination must include OR fall back gracefully
|
|
917
|
+
to the system stack.
|
|
918
|
+
============================================================ */
|
|
919
|
+
.wb-article-host[dir="rtl"][lang^="he"] {
|
|
920
|
+
--wb-font-display: "Heebo", "Assistant", "Rubik", system-ui, sans-serif;
|
|
921
|
+
--wb-font-body: "Heebo", "Assistant", "Rubik", system-ui, sans-serif;
|
|
922
|
+
line-height: 1.85; /* Hebrew x-height needs a touch more leading */
|
|
923
|
+
letter-spacing: 0; /* Hebrew rendering is tighter; reset any tracking. */
|
|
924
|
+
}
|
|
925
|
+
.wb-article-host[dir="rtl"][lang^="he"] h1,
|
|
926
|
+
.wb-article-host[dir="rtl"][lang^="he"] h2,
|
|
927
|
+
.wb-article-host[dir="rtl"][lang^="he"] h3 {
|
|
928
|
+
font-weight: 700; /* Hebrew display weights need bumping vs Latin */
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
.wb-article-host[dir="rtl"][lang^="ar"] {
|
|
932
|
+
--wb-font-display: "Noto Naskh Arabic", "Cairo", "Tajawal", system-ui, sans-serif;
|
|
933
|
+
--wb-font-body: "Noto Naskh Arabic", "Cairo", "Tajawal", system-ui, sans-serif;
|
|
934
|
+
line-height: 1.9; /* Arabic script benefits from extra leading */
|
|
935
|
+
letter-spacing: 0;
|
|
936
|
+
}
|
|
937
|
+
.wb-article-host[dir="rtl"][lang^="ar"] h1,
|
|
938
|
+
.wb-article-host[dir="rtl"][lang^="ar"] h2,
|
|
939
|
+
.wb-article-host[dir="rtl"][lang^="ar"] h3 {
|
|
940
|
+
font-weight: 700;
|
|
941
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mentionwell",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "Destination-side API reader + styles for Mentionwell-generated blog posts.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Isaac Horowitz <horowitzisaac@gmail.com>",
|
|
7
|
-
"homepage": "https://
|
|
7
|
+
"homepage": "https://mentionwell.com",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/
|
|
10
|
+
"url": "git+https://github.com/ZipLyne-Agency/MentionWell.git",
|
|
11
11
|
"directory": "packages/blog-reader"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
"access": "public"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"typescript": "^
|
|
52
|
+
"typescript": "^6.0.3"
|
|
53
53
|
}
|
|
54
54
|
}
|