@scalemule/news-publication 0.0.21 → 0.0.23

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.
@@ -0,0 +1,23 @@
1
+ import * as react from 'react';
2
+ import { V as VerifiedCard } from './types-DFDCZHbS.cjs';
3
+
4
+ /**
5
+ * Validate that an action link is safe for readers.
6
+ * Rejects javascript:, data:, blob:, credentials, and loopback/internal hosts.
7
+ */
8
+ declare function isSafeActionUrl(raw: unknown): boolean;
9
+ /**
10
+ * Sanitize and project raw API metadata cards into strictly validated `VerifiedCard[]`.
11
+ * If rawCards is empty or absent and a slug is provided, checks the curated community cards registry.
12
+ */
13
+ declare function getArticleCards(rawCards?: unknown, slug?: string): VerifiedCard[];
14
+ declare function VerifiedCardComponent({ card, className, }: {
15
+ card: VerifiedCard;
16
+ className?: string;
17
+ }): react.JSX.Element;
18
+ declare function VerifiedCardSection({ cards, className, }: {
19
+ cards?: VerifiedCard[];
20
+ className?: string;
21
+ }): react.JSX.Element | null;
22
+
23
+ export { VerifiedCardComponent, VerifiedCardSection, getArticleCards, isSafeActionUrl };
@@ -0,0 +1,23 @@
1
+ import * as react from 'react';
2
+ import { V as VerifiedCard } from './types-DFDCZHbS.js';
3
+
4
+ /**
5
+ * Validate that an action link is safe for readers.
6
+ * Rejects javascript:, data:, blob:, credentials, and loopback/internal hosts.
7
+ */
8
+ declare function isSafeActionUrl(raw: unknown): boolean;
9
+ /**
10
+ * Sanitize and project raw API metadata cards into strictly validated `VerifiedCard[]`.
11
+ * If rawCards is empty or absent and a slug is provided, checks the curated community cards registry.
12
+ */
13
+ declare function getArticleCards(rawCards?: unknown, slug?: string): VerifiedCard[];
14
+ declare function VerifiedCardComponent({ card, className, }: {
15
+ card: VerifiedCard;
16
+ className?: string;
17
+ }): react.JSX.Element;
18
+ declare function VerifiedCardSection({ cards, className, }: {
19
+ cards?: VerifiedCard[];
20
+ className?: string;
21
+ }): react.JSX.Element | null;
22
+
23
+ export { VerifiedCardComponent, VerifiedCardSection, getArticleCards, isSafeActionUrl };
@@ -0,0 +1 @@
1
+ export { VerifiedCardComponent, VerifiedCardSection, getArticleCards, isSafeActionUrl } from './chunk-FMCHQI7K.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalemule/news-publication",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "description": "Shared server framework for ScaleMule local news publications. Walnut Creek Times is the broadsheet default; each paper supplies its own identity and feature flags.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -69,13 +69,20 @@
69
69
  "types": "./dist/network-bar.d.ts",
70
70
  "import": "./dist/network-bar.js",
71
71
  "require": "./dist/network-bar.cjs"
72
- }
72
+ },
73
+ "./verified-card": {
74
+ "types": "./dist/verified-card.d.ts",
75
+ "import": "./dist/verified-card.js",
76
+ "require": "./dist/verified-card.cjs"
77
+ },
78
+ "./verified-card.css": "./verified-card.css"
73
79
  },
74
80
  "files": [
75
81
  "dist",
76
82
  "tokens",
77
83
  "marketplace.css",
78
84
  "cookie-consent.css",
85
+ "verified-card.css",
79
86
  "README.md",
80
87
  "LICENSE"
81
88
  ],
@@ -263,3 +263,213 @@
263
263
  text-decoration: underline;
264
264
  text-underline-offset: 3px;
265
265
  }
266
+
267
+ /*
268
+ * Broadsheet Verified Factsheet Card
269
+ */
270
+ .article-verified-card {
271
+ margin: 2.25rem 0 2rem 0;
272
+ border: 1px solid var(--pub-rule, var(--news-border, #d7dcd7));
273
+ border-top: 3px solid var(--pub-accent, var(--news-nameplate, #bb171d));
274
+ background-color: var(--pub-paper, var(--news-paper, #ffffff));
275
+ color: var(--pub-ink, var(--news-ink, #171917));
276
+ padding: 1.5rem 1.75rem;
277
+ box-sizing: border-box;
278
+ }
279
+
280
+ @media (max-width: 640px) {
281
+ .article-verified-card {
282
+ padding: 1.25rem 1rem;
283
+ margin: 1.75rem 0 1.5rem 0;
284
+ }
285
+ }
286
+
287
+ .article-verified-card__header {
288
+ display: flex;
289
+ align-items: center;
290
+ justify-content: space-between;
291
+ gap: 0.75rem;
292
+ margin-bottom: 0.5rem;
293
+ }
294
+
295
+ .article-verified-card__kicker {
296
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
297
+ font-size: 0.6875rem;
298
+ font-weight: 700;
299
+ letter-spacing: 0.08em;
300
+ text-transform: uppercase;
301
+ color: var(--pub-accent, var(--news-nameplate, #bb171d));
302
+ margin: 0;
303
+ }
304
+
305
+ .article-verified-card__badge {
306
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
307
+ font-size: 0.6875rem;
308
+ font-weight: 600;
309
+ color: var(--pub-ink, var(--news-ink, #171917));
310
+ background-color: var(--pub-soft, #f0f2f0);
311
+ padding: 0.2rem 0.55rem;
312
+ border-radius: 2px;
313
+ white-space: nowrap;
314
+ }
315
+
316
+ .article-verified-card__title {
317
+ font-family: var(--pub-serif, Georgia, "Times New Roman", serif);
318
+ font-size: 1.375rem;
319
+ font-weight: 700;
320
+ line-height: 1.25;
321
+ color: var(--pub-ink, var(--news-ink, #171917));
322
+ margin: 0.25rem 0 0.25rem 0;
323
+ }
324
+
325
+ @media (max-width: 640px) {
326
+ .article-verified-card__title {
327
+ font-size: 1.25rem;
328
+ }
329
+ }
330
+
331
+ .article-verified-card__subtitle {
332
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
333
+ font-size: 0.875rem;
334
+ color: var(--pub-muted, var(--news-muted, #545c55));
335
+ margin: 0 0 0.875rem 0;
336
+ line-height: 1.4;
337
+ }
338
+
339
+ .article-verified-card__summary {
340
+ font-family: var(--pub-serif, Georgia, "Times New Roman", serif);
341
+ font-size: 0.9375rem;
342
+ line-height: 1.5;
343
+ color: var(--pub-ink, #2d312e);
344
+ margin: 0 0 1.25rem 0;
345
+ }
346
+
347
+ .article-verified-card__fact-grid {
348
+ display: grid;
349
+ grid-template-columns: 1fr;
350
+ gap: 0.625rem;
351
+ border-top: 1px solid var(--pub-rule, #eef0ee);
352
+ border-bottom: 1px solid var(--pub-rule, #eef0ee);
353
+ padding: 1rem 0;
354
+ margin: 0 0 1.25rem 0;
355
+ }
356
+
357
+ .article-verified-card__fact-row {
358
+ display: flex;
359
+ flex-direction: row;
360
+ align-items: baseline;
361
+ gap: 1rem;
362
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
363
+ font-size: 0.875rem;
364
+ line-height: 1.4;
365
+ }
366
+
367
+ @media (max-width: 540px) {
368
+ .article-verified-card__fact-row {
369
+ flex-direction: column;
370
+ gap: 0.125rem;
371
+ }
372
+ }
373
+
374
+ .article-verified-card__fact-label {
375
+ min-width: 140px;
376
+ font-size: 0.6875rem;
377
+ font-weight: 700;
378
+ letter-spacing: 0.05em;
379
+ text-transform: uppercase;
380
+ color: var(--pub-muted, var(--news-muted, #545c55));
381
+ flex-shrink: 0;
382
+ margin: 0;
383
+ }
384
+
385
+ .article-verified-card__fact-value {
386
+ color: var(--pub-ink, var(--news-ink, #171917));
387
+ font-weight: 500;
388
+ margin: 0;
389
+ }
390
+
391
+ .article-verified-card__fact-link {
392
+ color: var(--pub-ink, var(--news-ink, #171917));
393
+ text-decoration: underline;
394
+ text-underline-offset: 3px;
395
+ text-decoration-color: var(--pub-muted, #a0a6a0);
396
+ transition: color 0.15s ease, text-decoration-color 0.15s ease;
397
+ }
398
+
399
+ .article-verified-card__fact-link:hover {
400
+ color: var(--pub-accent, var(--news-nameplate, #bb171d));
401
+ text-decoration-color: var(--pub-accent, var(--news-nameplate, #bb171d));
402
+ }
403
+
404
+ .article-verified-card__actions {
405
+ display: flex;
406
+ flex-wrap: wrap;
407
+ gap: 0.75rem;
408
+ margin: 1.25rem 0 0 0;
409
+ }
410
+
411
+ .article-verified-card__action {
412
+ display: inline-flex;
413
+ align-items: center;
414
+ justify-content: center;
415
+ gap: 0.375rem;
416
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
417
+ font-size: 0.8125rem;
418
+ font-weight: 600;
419
+ border-radius: 2px;
420
+ text-decoration: none !important;
421
+ transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
422
+ }
423
+
424
+ .article-verified-card__action--primary {
425
+ background-color: var(--pub-ink, var(--news-ink, #171917));
426
+ color: var(--pub-paper, #ffffff) !important;
427
+ padding: 0.625rem 1.125rem;
428
+ }
429
+
430
+ .article-verified-card__action--primary:hover {
431
+ background-color: var(--pub-accent, var(--news-nameplate, #bb171d));
432
+ }
433
+
434
+ .article-verified-card__action--secondary {
435
+ background-color: transparent;
436
+ color: var(--pub-ink, var(--news-ink, #171917)) !important;
437
+ border: 1px solid var(--pub-ink, var(--news-ink, #171917));
438
+ padding: 0.5625rem 1rem;
439
+ }
440
+
441
+ .article-verified-card__action--secondary:hover {
442
+ background-color: var(--pub-soft, #f2f4f2);
443
+ }
444
+
445
+ .article-verified-card__footer {
446
+ border-top: 1px solid var(--pub-rule, #eef0ee);
447
+ margin-top: 1.25rem;
448
+ padding-top: 0.75rem;
449
+ display: flex;
450
+ flex-wrap: wrap;
451
+ align-items: center;
452
+ justify-content: space-between;
453
+ gap: 0.5rem;
454
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
455
+ font-size: 0.75rem;
456
+ color: var(--pub-muted, var(--news-muted, #545c55));
457
+ }
458
+
459
+ .article-verified-card__seal {
460
+ display: inline-flex;
461
+ align-items: center;
462
+ gap: 0.375rem;
463
+ color: var(--pub-sponsor, #173e32);
464
+ font-weight: 600;
465
+ }
466
+
467
+ .article-verified-card__seal-check {
468
+ color: var(--pub-sponsor, #173e32);
469
+ font-weight: 700;
470
+ }
471
+
472
+ .article-verified-card__date {
473
+ color: var(--pub-muted, var(--news-muted, #545c55));
474
+ font-weight: 400;
475
+ }
@@ -0,0 +1,208 @@
1
+ /* Broadsheet Verified Factsheet Card — WSJ & The Economist aesthetic */
2
+
3
+ .article-verified-card {
4
+ margin: 2.25rem 0 2rem 0;
5
+ border: 1px solid var(--pub-rule, var(--news-border, #d7dcd7));
6
+ border-top: 3px solid var(--pub-accent, var(--news-nameplate, #bb171d));
7
+ background-color: var(--pub-paper, var(--news-paper, #ffffff));
8
+ color: var(--pub-ink, var(--news-ink, #171917));
9
+ padding: 1.5rem 1.75rem;
10
+ box-sizing: border-box;
11
+ }
12
+
13
+ @media (max-width: 640px) {
14
+ .article-verified-card {
15
+ padding: 1.25rem 1rem;
16
+ margin: 1.75rem 0 1.5rem 0;
17
+ }
18
+ }
19
+
20
+ .article-verified-card__header {
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: space-between;
24
+ gap: 0.75rem;
25
+ margin-bottom: 0.5rem;
26
+ }
27
+
28
+ .article-verified-card__kicker {
29
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
30
+ font-size: 0.6875rem;
31
+ font-weight: 700;
32
+ letter-spacing: 0.08em;
33
+ text-transform: uppercase;
34
+ color: var(--pub-accent, var(--news-nameplate, #bb171d));
35
+ margin: 0;
36
+ }
37
+
38
+ .article-verified-card__badge {
39
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
40
+ font-size: 0.6875rem;
41
+ font-weight: 600;
42
+ color: var(--pub-ink, var(--news-ink, #171917));
43
+ background-color: var(--pub-soft, #f0f2f0);
44
+ padding: 0.2rem 0.55rem;
45
+ border-radius: 2px;
46
+ white-space: nowrap;
47
+ }
48
+
49
+ .article-verified-card__title {
50
+ font-family: var(--pub-serif, Georgia, "Times New Roman", serif);
51
+ font-size: 1.375rem;
52
+ font-weight: 700;
53
+ line-height: 1.25;
54
+ color: var(--pub-ink, var(--news-ink, #171917));
55
+ margin: 0.25rem 0 0.25rem 0;
56
+ }
57
+
58
+ @media (max-width: 640px) {
59
+ .article-verified-card__title {
60
+ font-size: 1.25rem;
61
+ }
62
+ }
63
+
64
+ .article-verified-card__subtitle {
65
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
66
+ font-size: 0.875rem;
67
+ color: var(--pub-muted, var(--news-muted, #545c55));
68
+ margin: 0 0 0.875rem 0;
69
+ line-height: 1.4;
70
+ }
71
+
72
+ .article-verified-card__summary {
73
+ font-family: var(--pub-serif, Georgia, "Times New Roman", serif);
74
+ font-size: 0.9375rem;
75
+ line-height: 1.5;
76
+ color: var(--pub-ink, #2d312e);
77
+ margin: 0 0 1.25rem 0;
78
+ }
79
+
80
+ .article-verified-card__fact-grid {
81
+ display: grid;
82
+ grid-template-columns: 1fr;
83
+ gap: 0.625rem;
84
+ border-top: 1px solid var(--pub-rule, #eef0ee);
85
+ border-bottom: 1px solid var(--pub-rule, #eef0ee);
86
+ padding: 1rem 0;
87
+ margin: 0 0 1.25rem 0;
88
+ }
89
+
90
+ .article-verified-card__fact-row {
91
+ display: flex;
92
+ flex-direction: row;
93
+ align-items: baseline;
94
+ gap: 1rem;
95
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
96
+ font-size: 0.875rem;
97
+ line-height: 1.4;
98
+ }
99
+
100
+ @media (max-width: 540px) {
101
+ .article-verified-card__fact-row {
102
+ flex-direction: column;
103
+ gap: 0.125rem;
104
+ }
105
+ }
106
+
107
+ .article-verified-card__fact-label {
108
+ min-width: 140px;
109
+ font-size: 0.6875rem;
110
+ font-weight: 700;
111
+ letter-spacing: 0.05em;
112
+ text-transform: uppercase;
113
+ color: var(--pub-muted, var(--news-muted, #545c55));
114
+ flex-shrink: 0;
115
+ margin: 0;
116
+ }
117
+
118
+ .article-verified-card__fact-value {
119
+ color: var(--pub-ink, var(--news-ink, #171917));
120
+ font-weight: 500;
121
+ margin: 0;
122
+ }
123
+
124
+ .article-verified-card__fact-link {
125
+ color: var(--pub-ink, var(--news-ink, #171917));
126
+ text-decoration: underline;
127
+ text-underline-offset: 3px;
128
+ text-decoration-color: var(--pub-muted, #a0a6a0);
129
+ transition: color 0.15s ease, text-decoration-color 0.15s ease;
130
+ }
131
+
132
+ .article-verified-card__fact-link:hover {
133
+ color: var(--pub-accent, var(--news-nameplate, #bb171d));
134
+ text-decoration-color: var(--pub-accent, var(--news-nameplate, #bb171d));
135
+ }
136
+
137
+ .article-verified-card__actions {
138
+ display: flex;
139
+ flex-wrap: wrap;
140
+ gap: 0.75rem;
141
+ margin: 1.25rem 0 0 0;
142
+ }
143
+
144
+ .article-verified-card__action {
145
+ display: inline-flex;
146
+ align-items: center;
147
+ justify-content: center;
148
+ gap: 0.375rem;
149
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
150
+ font-size: 0.8125rem;
151
+ font-weight: 600;
152
+ border-radius: 2px;
153
+ text-decoration: none !important;
154
+ transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
155
+ }
156
+
157
+ .article-verified-card__action--primary {
158
+ background-color: var(--pub-ink, var(--news-ink, #171917));
159
+ color: var(--pub-paper, #ffffff) !important;
160
+ padding: 0.625rem 1.125rem;
161
+ }
162
+
163
+ .article-verified-card__action--primary:hover {
164
+ background-color: var(--pub-accent, var(--news-nameplate, #bb171d));
165
+ }
166
+
167
+ .article-verified-card__action--secondary {
168
+ background-color: transparent;
169
+ color: var(--pub-ink, var(--news-ink, #171917)) !important;
170
+ border: 1px solid var(--pub-ink, var(--news-ink, #171917));
171
+ padding: 0.5625rem 1rem;
172
+ }
173
+
174
+ .article-verified-card__action--secondary:hover {
175
+ background-color: var(--pub-soft, #f2f4f2);
176
+ }
177
+
178
+ .article-verified-card__footer {
179
+ border-top: 1px solid var(--pub-rule, #eef0ee);
180
+ margin-top: 1.25rem;
181
+ padding-top: 0.75rem;
182
+ display: flex;
183
+ flex-wrap: wrap;
184
+ align-items: center;
185
+ justify-content: space-between;
186
+ gap: 0.5rem;
187
+ font-family: var(--pub-sans, Arial, Helvetica, sans-serif);
188
+ font-size: 0.75rem;
189
+ color: var(--pub-muted, var(--news-muted, #545c55));
190
+ }
191
+
192
+ .article-verified-card__seal {
193
+ display: inline-flex;
194
+ align-items: center;
195
+ gap: 0.375rem;
196
+ color: var(--pub-sponsor, #173e32);
197
+ font-weight: 600;
198
+ }
199
+
200
+ .article-verified-card__seal-check {
201
+ color: var(--pub-sponsor, #173e32);
202
+ font-weight: 700;
203
+ }
204
+
205
+ .article-verified-card__date {
206
+ color: var(--pub-muted, var(--news-muted, #545c55));
207
+ font-weight: 400;
208
+ }