@certrev/cert-block 1.0.3 → 1.1.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +25 -6
  3. package/dist/builder/cert-chrome-data.d.ts +26 -1
  4. package/dist/builder/cert-chrome-data.d.ts.map +1 -1
  5. package/dist/builder/cert-chrome-data.js +1 -0
  6. package/dist/builder/cert-chrome-data.js.map +1 -1
  7. package/dist/builder/cert-review-card.d.ts +35 -2
  8. package/dist/builder/cert-review-card.d.ts.map +1 -1
  9. package/dist/builder/cert-review-card.js +112 -2
  10. package/dist/builder/cert-review-card.js.map +1 -1
  11. package/dist/builder/delivery-runtime.d.ts +23 -0
  12. package/dist/builder/delivery-runtime.d.ts.map +1 -0
  13. package/dist/builder/delivery-runtime.js +38 -0
  14. package/dist/builder/delivery-runtime.js.map +1 -0
  15. package/dist/builder/envelope-face.d.ts +63 -0
  16. package/dist/builder/envelope-face.d.ts.map +1 -0
  17. package/dist/builder/envelope-face.js +151 -0
  18. package/dist/builder/envelope-face.js.map +1 -0
  19. package/dist/builder/index.d.ts +15 -3
  20. package/dist/builder/index.d.ts.map +1 -1
  21. package/dist/builder/index.js +14 -2
  22. package/dist/builder/index.js.map +1 -1
  23. package/dist/builder/issuer-key.d.ts +12 -0
  24. package/dist/builder/issuer-key.d.ts.map +1 -0
  25. package/dist/builder/issuer-key.js +14 -0
  26. package/dist/builder/issuer-key.js.map +1 -0
  27. package/dist/components/memo-toggle.d.ts +42 -0
  28. package/dist/components/memo-toggle.d.ts.map +1 -0
  29. package/dist/components/memo-toggle.js +60 -0
  30. package/dist/components/memo-toggle.js.map +1 -0
  31. package/dist/components/render-cert-block.d.ts +9 -0
  32. package/dist/components/render-cert-block.d.ts.map +1 -1
  33. package/dist/components/render-cert-block.js +83 -25
  34. package/dist/components/render-cert-block.js.map +1 -1
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +3 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/modal/certrev-cert-modal.d.ts +34 -1
  40. package/dist/modal/certrev-cert-modal.d.ts.map +1 -1
  41. package/dist/modal/certrev-cert-modal.js +40 -2
  42. package/dist/modal/certrev-cert-modal.js.map +1 -1
  43. package/dist/modal/certrev-cert.entry.d.ts.map +1 -1
  44. package/dist/modal/certrev-cert.entry.js +2 -4
  45. package/dist/modal/certrev-cert.entry.js.map +1 -1
  46. package/dist/modal/certrev-cert.js +4 -4
  47. package/dist/modal/deprecated.d.ts +15 -0
  48. package/dist/modal/deprecated.d.ts.map +1 -0
  49. package/dist/modal/deprecated.js +22 -0
  50. package/dist/modal/deprecated.js.map +1 -0
  51. package/dist/modal/ftc-disclosure.d.ts +7 -3
  52. package/dist/modal/ftc-disclosure.d.ts.map +1 -1
  53. package/dist/modal/ftc-disclosure.js +7 -3
  54. package/dist/modal/ftc-disclosure.js.map +1 -1
  55. package/dist/modal/index.d.ts +4 -3
  56. package/dist/modal/index.d.ts.map +1 -1
  57. package/dist/modal/index.js +4 -3
  58. package/dist/modal/index.js.map +1 -1
  59. package/dist/modal/interactions.d.ts +20 -4
  60. package/dist/modal/interactions.d.ts.map +1 -1
  61. package/dist/modal/interactions.js +34 -7
  62. package/dist/modal/interactions.js.map +1 -1
  63. package/dist/verify/get-verified-delivery.d.ts +91 -0
  64. package/dist/verify/get-verified-delivery.d.ts.map +1 -0
  65. package/dist/verify/get-verified-delivery.js +157 -0
  66. package/dist/verify/get-verified-delivery.js.map +1 -0
  67. package/package.json +5 -1
  68. package/src/builder/cert-chrome-data.ts +27 -0
  69. package/src/builder/cert-review-card.tsx +143 -3
  70. package/src/builder/delivery-runtime.ts +54 -0
  71. package/src/builder/envelope-face.ts +173 -0
  72. package/src/builder/index.tsx +23 -1
  73. package/src/builder/issuer-key.ts +13 -0
  74. package/src/components/memo-toggle.ts +63 -0
  75. package/src/components/render-cert-block.ts +124 -28
  76. package/src/index.ts +28 -0
  77. package/src/modal/certrev-cert-modal.ts +45 -2
  78. package/src/modal/certrev-cert.entry.ts +2 -4
  79. package/src/modal/deprecated.ts +25 -0
  80. package/src/modal/ftc-disclosure.ts +7 -3
  81. package/src/modal/index.ts +4 -3
  82. package/src/modal/interactions.ts +37 -7
  83. package/src/verify/get-verified-delivery.ts +211 -0
  84. package/dist/modal/ftc-guard.d.ts +0 -85
  85. package/dist/modal/ftc-guard.d.ts.map +0 -1
  86. package/dist/modal/ftc-guard.js +0 -150
  87. package/dist/modal/ftc-guard.js.map +0 -1
  88. package/src/modal/ftc-guard.ts +0 -174
@@ -0,0 +1,63 @@
1
+ /**
2
+ * ─────────────────────────────────────────────────────────────────────────────
3
+ * `envelopeCardInput` — the Builder card's face, from VERIFIED facts + the brand's def (1.1.0)
4
+ * ─────────────────────────────────────────────────────────────────────────────
5
+ *
6
+ * The one mapping from a verified payload's `content` and the Delivery API's `renderDef` sibling
7
+ * to the `renderCertBlock` input the registered `CertReviewCard` paints. It is its own module,
8
+ * react-free, and exported on the `./builder/face` subpath so the portal's server bundle (which
9
+ * cannot load `./builder`: that entry creates a React context at import) renders its preview
10
+ * through THIS function instead of a copy of it. A preview and the live card that share the
11
+ * mapping cannot disagree about it.
12
+ *
13
+ * The facts are read exactly as the Shopify app embed reads the same envelope:
14
+ * - the credential is each verified credential's `cardLabel` (else `abbreviation`), joined, and
15
+ * only with the dated verification beside it; no date, no credential (the name-only face);
16
+ * - the compensation cue's PRESENCE is the only thing read; the words are the locked constant,
17
+ * and an absent or null cue is the pro-bono face with no cue;
18
+ * - the def's `hidden` set removes only what is hideable (`HIDEABLE_FIELDS`); a def cannot hide
19
+ * the scope line, the credential verification or the certificate link.
20
+ *
21
+ * The face is the PHONE-aware one (`responsive`): on a narrow viewport the banner header stacks and
22
+ * a long memo collapses behind a toggle the card binds (`memo-toggle.ts`); a wider viewport paints
23
+ * exactly what it would without it.
24
+ *
25
+ * The caller has already run the kernel. This function never decides WHETHER to render a cert;
26
+ * it only returns null when the verified content cannot make a face (no reviewer, no verify URL).
27
+ */
28
+ import type { CertBlockFace, CertBlockLayout, RenderCertBlockInput } from '../components/render-cert-block.js';
29
+ import { type ResolvedBlockTheme } from '../components/render-def.js';
30
+ import type { CertContent } from '../contract/kernel.js';
31
+ import type { CertChromeRenderDef } from './cert-chrome-data.js';
32
+ /**
33
+ * Every field id `renderCertBlock` places, in its canonical order. A def-driven face places all of
34
+ * them except what the def hides; `renderCertBlock` still gates each on its fact being present.
35
+ */
36
+ export declare const CERT_FACE_FIELDS: readonly ["label", "authorName", "authorTitle", "reviewerPhoto", "bylineCredentialed", "bylinePlain", "bio", "memo", "profileLink", "certificateLink", "scopeLine", "compensationCue"];
37
+ export interface EnvelopeCardOptions {
38
+ /** The placement the entry/editor chose. A recognised mode wins over the def's layout. */
39
+ readonly mode?: unknown;
40
+ /** Banner memo placement, passed through as on the options path. */
41
+ readonly part?: unknown;
42
+ }
43
+ /** The def's theme tokens as `renderCertBlock` theme input, with the accent ink derived. */
44
+ export declare function themeFromDef(def: CertChromeRenderDef | null): Partial<ResolvedBlockTheme> | undefined;
45
+ /** The face a def asks for: its custom composition, or every field minus the hideable ones it hides. */
46
+ export declare function faceFromDef(def: CertChromeRenderDef | null, layout: CertBlockLayout): CertBlockFace | undefined;
47
+ /**
48
+ * The layout: an editor-chosen mode, else the def's own layout (a custom face only when the def
49
+ * carries one), else banner, which is what the Shopify embed paints for a def with no layout and
50
+ * what every exported Builder entry has painted since 0.5.
51
+ */
52
+ export declare function layoutFor(def: CertChromeRenderDef | null, mode: unknown): CertBlockLayout;
53
+ /** The fused credential label the envelope's verified credentials stand for, or '' (name-only). */
54
+ export declare function credentialLabel(expert: Record<string, unknown>): {
55
+ credential: string;
56
+ verifiedAt: string;
57
+ } | null;
58
+ /**
59
+ * The exact `renderCertBlock` input for a verified envelope's content and the brand's def, or
60
+ * null when the content cannot make a face.
61
+ */
62
+ export declare function envelopeCardInput(content: CertContent, renderDef: CertChromeRenderDef | null, options?: EnvelopeCardOptions): RenderCertBlockInput | null;
63
+ //# sourceMappingURL=envelope-face.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope-face.d.ts","sourceRoot":"","sources":["../../src/builder/envelope-face.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EACX,aAAa,EACb,eAAe,EAEf,oBAAoB,EACpB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAA+C,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAClH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAEhE;;;GAGG;AACH,eAAO,MAAM,gBAAgB,wLAanB,CAAA;AAgBV,MAAM,WAAW,mBAAmB;IACnC,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,oEAAoE;IACpE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAerG;AAED,wGAAwG;AACxG,wBAAgB,WAAW,CAAC,GAAG,EAAE,mBAAmB,GAAG,IAAI,EAAE,MAAM,EAAE,eAAe,GAAG,aAAa,GAAG,SAAS,CAK/G;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,mBAAmB,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,eAAe,CAKzF;AAED,mGAAmG;AACnG,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAYlH;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,mBAAmB,GAAG,IAAI,EACrC,OAAO,GAAE,mBAAwB,GAC/B,oBAAoB,GAAG,IAAI,CAiC7B"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * ─────────────────────────────────────────────────────────────────────────────
3
+ * `envelopeCardInput` — the Builder card's face, from VERIFIED facts + the brand's def (1.1.0)
4
+ * ─────────────────────────────────────────────────────────────────────────────
5
+ *
6
+ * The one mapping from a verified payload's `content` and the Delivery API's `renderDef` sibling
7
+ * to the `renderCertBlock` input the registered `CertReviewCard` paints. It is its own module,
8
+ * react-free, and exported on the `./builder/face` subpath so the portal's server bundle (which
9
+ * cannot load `./builder`: that entry creates a React context at import) renders its preview
10
+ * through THIS function instead of a copy of it. A preview and the live card that share the
11
+ * mapping cannot disagree about it.
12
+ *
13
+ * The facts are read exactly as the Shopify app embed reads the same envelope:
14
+ * - the credential is each verified credential's `cardLabel` (else `abbreviation`), joined, and
15
+ * only with the dated verification beside it; no date, no credential (the name-only face);
16
+ * - the compensation cue's PRESENCE is the only thing read; the words are the locked constant,
17
+ * and an absent or null cue is the pro-bono face with no cue;
18
+ * - the def's `hidden` set removes only what is hideable (`HIDEABLE_FIELDS`); a def cannot hide
19
+ * the scope line, the credential verification or the certificate link.
20
+ *
21
+ * The face is the PHONE-aware one (`responsive`): on a narrow viewport the banner header stacks and
22
+ * a long memo collapses behind a toggle the card binds (`memo-toggle.ts`); a wider viewport paints
23
+ * exactly what it would without it.
24
+ *
25
+ * The caller has already run the kernel. This function never decides WHETHER to render a cert;
26
+ * it only returns null when the verified content cannot make a face (no reviewer, no verify URL).
27
+ */
28
+ import { accentFg, HIDEABLE_FIELDS, isOpaqueHexColor } from '../components/render-def.js';
29
+ /**
30
+ * Every field id `renderCertBlock` places, in its canonical order. A def-driven face places all of
31
+ * them except what the def hides; `renderCertBlock` still gates each on its fact being present.
32
+ */
33
+ export const CERT_FACE_FIELDS = [
34
+ 'label',
35
+ 'authorName',
36
+ 'authorTitle',
37
+ 'reviewerPhoto',
38
+ 'bylineCredentialed',
39
+ 'bylinePlain',
40
+ 'bio',
41
+ 'memo',
42
+ 'profileLink',
43
+ 'certificateLink',
44
+ 'scopeLine',
45
+ 'compensationCue',
46
+ ];
47
+ const MODES = ['banner', 'sidebar', 'floating'];
48
+ function isMode(v) {
49
+ return typeof v === 'string' && MODES.includes(v);
50
+ }
51
+ function text(v) {
52
+ return typeof v === 'string' ? v : '';
53
+ }
54
+ function optionalText(v) {
55
+ return text(v).trim() !== '' ? v : undefined;
56
+ }
57
+ /** The def's theme tokens as `renderCertBlock` theme input, with the accent ink derived. */
58
+ export function themeFromDef(def) {
59
+ const tokens = def?.tokens;
60
+ if (!tokens)
61
+ return undefined;
62
+ const accentColor = optionalText(tokens.accentColor);
63
+ return {
64
+ accentColor,
65
+ surface: optionalText(tokens.surface),
66
+ cornerRadius: optionalText(tokens.cornerRadius),
67
+ fontSlot: optionalText(tokens.fontSlot),
68
+ // The ink painted over the accent fill, derived the way the portal derives it, so a black
69
+ // accent carries white ink. Omitted for an accent `resolveBlockTheme` would reject anyway.
70
+ ...(accentColor && isOpaqueHexColor(accentColor) ? { accentFg: accentFg(accentColor) } : {}),
71
+ barInk: optionalText(tokens.barInk),
72
+ inkColor: optionalText(tokens.inkColor),
73
+ };
74
+ }
75
+ /** The face a def asks for: its custom composition, or every field minus the hideable ones it hides. */
76
+ export function faceFromDef(def, layout) {
77
+ if (!def)
78
+ return undefined;
79
+ if (layout === 'custom')
80
+ return { rung: def.rung, placedFields: [...(def.customFace?.placedFields ?? [])] };
81
+ const hidden = new Set(def.hidden.filter((id) => HIDEABLE_FIELDS.includes(id)));
82
+ return { rung: def.rung, placedFields: CERT_FACE_FIELDS.filter((id) => !hidden.has(id)) };
83
+ }
84
+ /**
85
+ * The layout: an editor-chosen mode, else the def's own layout (a custom face only when the def
86
+ * carries one), else banner, which is what the Shopify embed paints for a def with no layout and
87
+ * what every exported Builder entry has painted since 0.5.
88
+ */
89
+ export function layoutFor(def, mode) {
90
+ if (isMode(mode))
91
+ return mode;
92
+ if (def?.layout === 'custom' && def.customFace)
93
+ return 'custom';
94
+ if (isMode(def?.layout))
95
+ return def.layout;
96
+ return 'banner';
97
+ }
98
+ /** The fused credential label the envelope's verified credentials stand for, or '' (name-only). */
99
+ export function credentialLabel(expert) {
100
+ const verifiedAt = optionalText(expert.credentialVerifiedAt);
101
+ if (!verifiedAt)
102
+ return null;
103
+ const creds = Array.isArray(expert.credentials) ? expert.credentials : [];
104
+ const credential = creds
105
+ .map((c) => {
106
+ const rec = (typeof c === 'object' && c !== null ? c : {});
107
+ return optionalText(rec.cardLabel) ?? optionalText(rec.abbreviation);
108
+ })
109
+ .filter((l) => l !== undefined)
110
+ .join(', ');
111
+ return credential ? { credential, verifiedAt } : null;
112
+ }
113
+ /**
114
+ * The exact `renderCertBlock` input for a verified envelope's content and the brand's def, or
115
+ * null when the content cannot make a face.
116
+ */
117
+ export function envelopeCardInput(content, renderDef, options = {}) {
118
+ const expert = (content?.expert ?? {});
119
+ const author = (content?.author ?? {});
120
+ const reviewerName = text(expert.displayName);
121
+ const verifyUrl = text(content?.verifyUrl);
122
+ if (!reviewerName || !verifyUrl)
123
+ return null;
124
+ const cred = credentialLabel(expert);
125
+ const layout = layoutFor(renderDef, options.mode);
126
+ const face = faceFromDef(renderDef, layout);
127
+ const theme = themeFromDef(renderDef);
128
+ const part = options.part === 'full' || options.part === 'header' || options.part === 'memo' ? options.part : undefined;
129
+ return {
130
+ mode: layout,
131
+ ...(theme ? { theme } : {}),
132
+ ...(face ? { face } : {}),
133
+ ...(part ? { part } : {}),
134
+ responsive: true,
135
+ facts: {
136
+ authorName: optionalText(author.name) ?? 'Editorial',
137
+ authorTitle: optionalText(author.title),
138
+ reviewerName,
139
+ credential: cred?.credential ?? '',
140
+ credentialVerifiedAt: cred?.verifiedAt ?? '',
141
+ certifiedAt: text(content.certifiedAt),
142
+ memo: text(content.memo),
143
+ bio: optionalText(expert.bio),
144
+ profileUrl: text(expert.profileUrl),
145
+ certificateUrl: verifyUrl,
146
+ // Presence only: a cue string renders the locked constant; absent or null is pro-bono.
147
+ compensationCue: optionalText(expert.compensationCue) ? undefined : null,
148
+ },
149
+ };
150
+ }
151
+ //# sourceMappingURL=envelope-face.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope-face.js","sourceRoot":"","sources":["../../src/builder/envelope-face.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@
12
12
  * another article, and there is no `placementId` input to forge or mis-select.
13
13
  *
14
14
  * THE PUSH KIT DOES NOT INHERIT THAT PROPERTY, and this module exports it too. `CertReviewCard` /
15
- * `certRevCertComponent` register the 19 wire-type fields — `reviewerName`,
15
+ * `certRevCertComponent` register the 20 wire-type fields — `reviewerName`,
16
16
  * `credentialVerification`, `verifyUrl`, `memo` — as Builder INPUTS, and the card renders what
17
17
  * those inputs hold; it runs no signature check and consults no verdict. `advanced: true` folds
18
18
  * them out of the editor's default view, which is a UI reveal and not a lock, and `safeHttpUrl`
@@ -22,6 +22,17 @@
22
22
  * narrows it. See "PUSH trust model" in the package README for the full statement — including
23
23
  * what a revocation upstream does and does not reach.
24
24
  *
25
+ * 1.1.0 NARROWS THAT FOR A BLOCK CARRYING THE `delivery` MARKER (`{ v: 1, baseUrl }`, which the
26
+ * CertREV exporter writes). Such a block ignores every other option: it reads the signed envelope
27
+ * for the entry it renders inside (`builderContext.content.id`) from the CertREV Delivery API on
28
+ * `baseUrl` (an https certrev.com origin, nothing else), verifies it against the baked
29
+ * `cert-issuer-1` key, re-judges revocation and expiry at every render, and paints the brand's
30
+ * render def served beside it. A revoked, expired, unverifiable or unreachable cert, a marker that
31
+ * is not exactly that shape, or a missing entry id renders nothing. A block WITHOUT the marker
32
+ * (every entry exported before 1.1.0) renders from its options exactly as 1.0.3 did, so the
33
+ * paragraph above still describes it: an editor who deletes the marker gets the options face back,
34
+ * which is the 1.0.3 trust boundary, not a new one.
35
+ *
25
36
  * Three things the card DOES enforce, and they are the limit of it: no chrome at all without a
26
37
  * `reviewerName` and a `verifyUrl`; a credential renders only welded to its dated verification
27
38
  * (the fused pair); and the FTC disclosures render from locked constants, so rewriting the
@@ -89,6 +100,7 @@ export interface CertRevBuilderRegistration {
89
100
  * (truth). Matched by NAME at render, so Write-API content works without visual-editor setup.
90
101
  */
91
102
  export declare const certRevAnchorComponent: CertRevBuilderRegistration;
92
- export { BUILDER_CERT_CHROME_KEYS, type BuilderCertChromeData, type BuilderCertChromeKey, type CertChromeRenderDef, } from './cert-chrome-data.js';
93
- export { BUILDER_REGISTRATION, type BuilderInput, CERT_COMPONENT_NAME, type CertBlockBuilderRegistration, CertReviewCard, type CertReviewCardProps, type CertReviewCardRegisteredComponent, certRevCertComponent, PLACEMENT_INPUTS, WIRE_INPUTS, } from './cert-review-card.js';
103
+ export { BUILDER_CERT_CHROME_KEYS, type BuilderCertChromeData, type BuilderCertChromeKey, type CertChromeRenderDef, type CertDeliveryMarker, } from './cert-chrome-data.js';
104
+ export { acceptedDeliveryMarker, BUILDER_REGISTRATION, type BuilderInput, CERT_COMPONENT_NAME, type CertBlockBuilderRegistration, CertReviewCard, type CertReviewCardProps, type CertReviewCardRegisteredComponent, certRevCertComponent, PLACEMENT_INPUTS, WIRE_INPUTS, } from './cert-review-card.js';
105
+ export { CERT_FACE_FIELDS, credentialLabel, type EnvelopeCardOptions, envelopeCardInput, faceFromDef, layoutFor, themeFromDef, } from './envelope-face.js';
94
106
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builder/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAA;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,sGAAsG;IACtG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CACzB;AASD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC/B,OAAO,EACP,SAAiB,EACjB,QAAQ,GACR,EAAE;IACF,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAC5B,+BAEA;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,gCAiBvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,uCAO5B;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C,SAAS,EAAE,OAAO,aAAa,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,KAAK,EAAE,CAAA;CACf;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,0BAIpC,CAAA;AAGD,OAAO,EACN,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACxB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,oBAAoB,EACpB,KAAK,YAAY,EACjB,mBAAmB,EACnB,KAAK,4BAA4B,EACjC,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,iCAAiC,EACtC,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,GACX,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builder/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAA;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,sGAAsG;IACtG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CACzB;AASD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC/B,OAAO,EACP,SAAiB,EACjB,QAAQ,GACR,EAAE;IACF,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAC5B,+BAEA;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,gCAiBvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,uCAO5B;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C,SAAS,EAAE,OAAO,aAAa,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,KAAK,EAAE,CAAA;CACf;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,0BAIpC,CAAA;AAGD,OAAO,EACN,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACvB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EACpB,KAAK,YAAY,EACjB,mBAAmB,EACnB,KAAK,4BAA4B,EACjC,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,iCAAiC,EACtC,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,GACX,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,gBAAgB,EAChB,eAAe,EACf,KAAK,mBAAmB,EACxB,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,YAAY,GACZ,MAAM,oBAAoB,CAAA"}
@@ -13,7 +13,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  * another article, and there is no `placementId` input to forge or mis-select.
14
14
  *
15
15
  * THE PUSH KIT DOES NOT INHERIT THAT PROPERTY, and this module exports it too. `CertReviewCard` /
16
- * `certRevCertComponent` register the 19 wire-type fields — `reviewerName`,
16
+ * `certRevCertComponent` register the 20 wire-type fields — `reviewerName`,
17
17
  * `credentialVerification`, `verifyUrl`, `memo` — as Builder INPUTS, and the card renders what
18
18
  * those inputs hold; it runs no signature check and consults no verdict. `advanced: true` folds
19
19
  * them out of the editor's default view, which is a UI reveal and not a lock, and `safeHttpUrl`
@@ -23,6 +23,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
23
  * narrows it. See "PUSH trust model" in the package README for the full statement — including
24
24
  * what a revocation upstream does and does not reach.
25
25
  *
26
+ * 1.1.0 NARROWS THAT FOR A BLOCK CARRYING THE `delivery` MARKER (`{ v: 1, baseUrl }`, which the
27
+ * CertREV exporter writes). Such a block ignores every other option: it reads the signed envelope
28
+ * for the entry it renders inside (`builderContext.content.id`) from the CertREV Delivery API on
29
+ * `baseUrl` (an https certrev.com origin, nothing else), verifies it against the baked
30
+ * `cert-issuer-1` key, re-judges revocation and expiry at every render, and paints the brand's
31
+ * render def served beside it. A revoked, expired, unverifiable or unreachable cert, a marker that
32
+ * is not exactly that shape, or a missing entry id renders nothing. A block WITHOUT the marker
33
+ * (every entry exported before 1.1.0) renders from its options exactly as 1.0.3 did, so the
34
+ * paragraph above still describes it: an editor who deletes the marker gets the options face back,
35
+ * which is the 1.0.3 trust boundary, not a new one.
36
+ *
26
37
  * Three things the card DOES enforce, and they are the limit of it: no chrome at all without a
27
38
  * `reviewerName` and a `verifyUrl`; a credential renders only welded to its dated verification
28
39
  * (the fused pair); and the FTC disclosures render from locked constants, so rewriting the
@@ -96,5 +107,6 @@ export const certRevAnchorComponent = {
96
107
  };
97
108
  // ── The Builder.io PUSH kit (CertReviewCard) + the single-sourced wire type ──
98
109
  export { BUILDER_CERT_CHROME_KEYS, } from './cert-chrome-data.js';
99
- export { BUILDER_REGISTRATION, CERT_COMPONENT_NAME, CertReviewCard, certRevCertComponent, PLACEMENT_INPUTS, WIRE_INPUTS, } from './cert-review-card.js';
110
+ export { acceptedDeliveryMarker, BUILDER_REGISTRATION, CERT_COMPONENT_NAME, CertReviewCard, certRevCertComponent, PLACEMENT_INPUTS, WIRE_INPUTS, } from './cert-review-card.js';
111
+ export { CERT_FACE_FIELDS, credentialLabel, envelopeCardInput, faceFromDef, layoutFor, themeFromDef, } from './envelope-face.js';
100
112
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/builder/index.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,OAAO,EAAE,aAAa,EAAkB,UAAU,EAAE,MAAM,OAAO,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAexD,MAAM,cAAc,GAAG,aAAa,CAAsB,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAA;AAE9F;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,EAC/B,OAAO,EACP,SAAS,GAAG,KAAK,EACjB,QAAQ,GAKR;IACA,OAAO,KAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,YAAG,QAAQ,GAA2B,CAAA;AACpG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB;IACvC,OAAO,CACN,kDACiC,EAAE,EAClC,KAAK,EAAE;YACN,MAAM,EAAE,oBAAoB;YAC5B,YAAY,EAAE,CAAC;YACf,OAAO,EAAE,WAAW;YACpB,IAAI,EAAE,gBAAgB;YACtB,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,SAAS;SACrB,iCAEe,8CAA0B,oJAErC,CACN,CAAA;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa;IAC5B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC,cAAc,CAAC,CAAA;IACzD,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACtD,OAAO,KAAC,UAAU,IAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,UAAU,SAAG,CAAA;IACrF,CAAC;IACD,IAAI,SAAS;QAAE,OAAO,KAAC,wBAAwB,KAAG,CAAA;IAClD,OAAO,IAAI,CAAA;AACZ,CAAC;AAaD;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA+B;IACjE,SAAS,EAAE,aAAa;IACxB,IAAI,EAAE,gBAAgB;IACtB,MAAM,EAAE,EAAE;CACV,CAAA;AAED,gFAAgF;AAChF,OAAO,EACN,wBAAwB,GAIxB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,oBAAoB,EAEpB,mBAAmB,EAEnB,cAAc,EAGd,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,GACX,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/builder/index.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,OAAO,EAAE,aAAa,EAAkB,UAAU,EAAE,MAAM,OAAO,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAexD,MAAM,cAAc,GAAG,aAAa,CAAsB,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAA;AAE9F;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,EAC/B,OAAO,EACP,SAAS,GAAG,KAAK,EACjB,QAAQ,GAKR;IACA,OAAO,KAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,YAAG,QAAQ,GAA2B,CAAA;AACpG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB;IACvC,OAAO,CACN,kDACiC,EAAE,EAClC,KAAK,EAAE;YACN,MAAM,EAAE,oBAAoB;YAC5B,YAAY,EAAE,CAAC;YACf,OAAO,EAAE,WAAW;YACpB,IAAI,EAAE,gBAAgB;YACtB,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,SAAS;SACrB,iCAEe,8CAA0B,oJAErC,CACN,CAAA;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa;IAC5B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC,cAAc,CAAC,CAAA;IACzD,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACtD,OAAO,KAAC,UAAU,IAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,UAAU,SAAG,CAAA;IACrF,CAAC;IACD,IAAI,SAAS;QAAE,OAAO,KAAC,wBAAwB,KAAG,CAAA;IAClD,OAAO,IAAI,CAAA;AACZ,CAAC;AAaD;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA+B;IACjE,SAAS,EAAE,aAAa;IACxB,IAAI,EAAE,gBAAgB;IACtB,MAAM,EAAE,EAAE;CACV,CAAA;AAED,gFAAgF;AAChF,OAAO,EACN,wBAAwB,GAKxB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EAEpB,mBAAmB,EAEnB,cAAc,EAGd,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,GACX,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,gBAAgB,EAChB,eAAe,EAEf,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,YAAY,GACZ,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The CertREV issuer PUBLIC key the envelope-backed Builder card verifies against (1.1.0).
3
+ *
4
+ * A copy of `CERT_ISSUER_KID` / `CERT_ISSUER_PUBLIC_KEY_PEM` in `modal/certrev-cert.entry.ts`, not
5
+ * an import of it: that entry registers a custom element and starts the storefront DOM passes at
6
+ * import, which a React server render must not do, and moving the constant out of it would change
7
+ * the storefront bundle the Shopify extension ships byte-for-byte. The two copies are pinned equal by
8
+ * `builder/__tests__/issuer-key.test.ts`, so a rotation that updates one and not the other fails.
9
+ */
10
+ export declare const CERT_ISSUER_KID = "cert-issuer-1";
11
+ export declare const CERT_ISSUER_PUBLIC_KEY_PEM = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAMWN956IOPjpAq900dL428VzA28TO/pVXnq3brwqUmwM=\n-----END PUBLIC KEY-----";
12
+ //# sourceMappingURL=issuer-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issuer-key.d.ts","sourceRoot":"","sources":["../../src/builder/issuer-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,kBAAkB,CAAA;AAC9C,eAAO,MAAM,0BAA0B,uHAEd,CAAA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The CertREV issuer PUBLIC key the envelope-backed Builder card verifies against (1.1.0).
3
+ *
4
+ * A copy of `CERT_ISSUER_KID` / `CERT_ISSUER_PUBLIC_KEY_PEM` in `modal/certrev-cert.entry.ts`, not
5
+ * an import of it: that entry registers a custom element and starts the storefront DOM passes at
6
+ * import, which a React server render must not do, and moving the constant out of it would change
7
+ * the storefront bundle the Shopify extension ships byte-for-byte. The two copies are pinned equal by
8
+ * `builder/__tests__/issuer-key.test.ts`, so a rotation that updates one and not the other fails.
9
+ */
10
+ export const CERT_ISSUER_KID = 'cert-issuer-1';
11
+ export const CERT_ISSUER_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
12
+ MCowBQYDK2VwAyEAMWN956IOPjpAq900dL428VzA28TO/pVXnq3brwqUmwM=
13
+ -----END PUBLIC KEY-----`;
14
+ //# sourceMappingURL=issuer-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issuer-key.js","sourceRoot":"","sources":["../../src/builder/issuer-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAA;AAC9C,MAAM,CAAC,MAAM,0BAA0B,GAAG;;yBAEjB,CAAA"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The PHONE face's collapsible memo (1.1.0): the markup contract `renderCertBlock` emits when its
3
+ * input asks for the responsive face, and the one toggle every host wires to it.
4
+ *
5
+ * On a viewport `NARROW_VIEWPORT` or narrower a long memo is clamped to `MEMO_COLLAPSED_LINES`
6
+ * lines behind a native `<button>` that expands it; wider viewports show the whole memo and no
7
+ * button. The state lives on the memo box (`data-certrev-memo="collapsed" | "open"`), never on a
8
+ * class, so a host stylesheet's `.open` rules cannot reach it; the button mirrors it on
9
+ * `aria-expanded` and in its label.
10
+ *
11
+ * Pure DOM, no React: the Builder card binds it on its wrapper, and any other host that paints the
12
+ * responsive face (a portal preview, a web component) calls the same function.
13
+ */
14
+ /** The memo box: the memo text and its toggle. The value is the state. */
15
+ export declare const MEMO_ATTR = "data-certrev-memo";
16
+ /** The clamped text inside the box. */
17
+ export declare const MEMO_TEXT_ATTR = "data-certrev-memo-text";
18
+ /** The expand/collapse button inside the box. */
19
+ export declare const MEMO_TOGGLE_ATTR = "data-certrev-memo-toggle";
20
+ export declare const MEMO_EXPAND_LABEL = "Read the full memo";
21
+ export declare const MEMO_COLLAPSE_LABEL = "Show less";
22
+ /** The viewport at or under which the phone face applies. */
23
+ export declare const NARROW_VIEWPORT = "(max-width: 640px)";
24
+ /** Lines a collapsed memo keeps. */
25
+ export declare const MEMO_COLLAPSED_LINES = 4;
26
+ /**
27
+ * A memo shorter than this, with fewer line breaks than `MEMO_COLLAPSE_MIN_BREAKS`, fits its
28
+ * collapsed lines on a phone (about 33 characters a line at 393px), so it gets no toggle: a button
29
+ * that reveals nothing is noise.
30
+ */
31
+ export declare const MEMO_COLLAPSE_MIN_CHARS = 160;
32
+ export declare const MEMO_COLLAPSE_MIN_BREAKS = 4;
33
+ /** Is this memo long enough to collapse on a phone? (No memo never does.) */
34
+ export declare function memoCollapses(memo: string | null | undefined): boolean;
35
+ /** The toggle a click landed on (the button or anything inside it), or null. */
36
+ export declare function memoToggleFor(target: EventTarget | null): Element | null;
37
+ /**
38
+ * Flip the memo box a toggle belongs to, mirroring the state on the button. Returns the new state
39
+ * (true = expanded), or null when the button is not inside a memo box.
40
+ */
41
+ export declare function toggleMemo(button: Element): boolean | null;
42
+ //# sourceMappingURL=memo-toggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memo-toggle.d.ts","sourceRoot":"","sources":["../../src/components/memo-toggle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,0EAA0E;AAC1E,eAAO,MAAM,SAAS,sBAAsB,CAAA;AAC5C,uCAAuC;AACvC,eAAO,MAAM,cAAc,2BAA2B,CAAA;AACtD,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,6BAA6B,CAAA;AAE1D,eAAO,MAAM,iBAAiB,uBAAuB,CAAA;AACrD,eAAO,MAAM,mBAAmB,cAAc,CAAA;AAE9C,6DAA6D;AAC7D,eAAO,MAAM,eAAe,uBAAuB,CAAA;AACnD,oCAAoC;AACpC,eAAO,MAAM,oBAAoB,IAAI,CAAA;AAErC;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAA;AAC1C,eAAO,MAAM,wBAAwB,IAAuB,CAAA;AAE5D,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAGtE;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAIxE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAQ1D"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The PHONE face's collapsible memo (1.1.0): the markup contract `renderCertBlock` emits when its
3
+ * input asks for the responsive face, and the one toggle every host wires to it.
4
+ *
5
+ * On a viewport `NARROW_VIEWPORT` or narrower a long memo is clamped to `MEMO_COLLAPSED_LINES`
6
+ * lines behind a native `<button>` that expands it; wider viewports show the whole memo and no
7
+ * button. The state lives on the memo box (`data-certrev-memo="collapsed" | "open"`), never on a
8
+ * class, so a host stylesheet's `.open` rules cannot reach it; the button mirrors it on
9
+ * `aria-expanded` and in its label.
10
+ *
11
+ * Pure DOM, no React: the Builder card binds it on its wrapper, and any other host that paints the
12
+ * responsive face (a portal preview, a web component) calls the same function.
13
+ */
14
+ /** The memo box: the memo text and its toggle. The value is the state. */
15
+ export const MEMO_ATTR = 'data-certrev-memo';
16
+ /** The clamped text inside the box. */
17
+ export const MEMO_TEXT_ATTR = 'data-certrev-memo-text';
18
+ /** The expand/collapse button inside the box. */
19
+ export const MEMO_TOGGLE_ATTR = 'data-certrev-memo-toggle';
20
+ export const MEMO_EXPAND_LABEL = 'Read the full memo';
21
+ export const MEMO_COLLAPSE_LABEL = 'Show less';
22
+ /** The viewport at or under which the phone face applies. */
23
+ export const NARROW_VIEWPORT = '(max-width: 640px)';
24
+ /** Lines a collapsed memo keeps. */
25
+ export const MEMO_COLLAPSED_LINES = 4;
26
+ /**
27
+ * A memo shorter than this, with fewer line breaks than `MEMO_COLLAPSE_MIN_BREAKS`, fits its
28
+ * collapsed lines on a phone (about 33 characters a line at 393px), so it gets no toggle: a button
29
+ * that reveals nothing is noise.
30
+ */
31
+ export const MEMO_COLLAPSE_MIN_CHARS = 160;
32
+ export const MEMO_COLLAPSE_MIN_BREAKS = MEMO_COLLAPSED_LINES;
33
+ /** Is this memo long enough to collapse on a phone? (No memo never does.) */
34
+ export function memoCollapses(memo) {
35
+ if (!memo)
36
+ return false;
37
+ return memo.length > MEMO_COLLAPSE_MIN_CHARS || memo.split('\n').length - 1 >= MEMO_COLLAPSE_MIN_BREAKS;
38
+ }
39
+ /** The toggle a click landed on (the button or anything inside it), or null. */
40
+ export function memoToggleFor(target) {
41
+ const el = target;
42
+ if (!el || typeof el.closest !== 'function')
43
+ return null;
44
+ return el.closest(`[${MEMO_TOGGLE_ATTR}]`);
45
+ }
46
+ /**
47
+ * Flip the memo box a toggle belongs to, mirroring the state on the button. Returns the new state
48
+ * (true = expanded), or null when the button is not inside a memo box.
49
+ */
50
+ export function toggleMemo(button) {
51
+ const box = button.closest(`[${MEMO_ATTR}]`);
52
+ if (!box)
53
+ return null;
54
+ const open = box.getAttribute(MEMO_ATTR) !== 'open';
55
+ box.setAttribute(MEMO_ATTR, open ? 'open' : 'collapsed');
56
+ button.setAttribute('aria-expanded', open ? 'true' : 'false');
57
+ button.textContent = open ? MEMO_COLLAPSE_LABEL : MEMO_EXPAND_LABEL;
58
+ return open;
59
+ }
60
+ //# sourceMappingURL=memo-toggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memo-toggle.js","sourceRoot":"","sources":["../../src/components/memo-toggle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAA;AAC5C,uCAAuC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,wBAAwB,CAAA;AACtD,iDAAiD;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAA;AAE1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAA;AACrD,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAA;AAE9C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,oBAAoB,CAAA;AACnD,oCAAoC;AACpC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAA;AAErC;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAA;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,oBAAoB,CAAA;AAE5D,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,IAA+B;IAC5D,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAA;IACvB,OAAO,IAAI,CAAC,MAAM,GAAG,uBAAuB,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,wBAAwB,CAAA;AACxG,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,MAA0B;IACvD,MAAM,EAAE,GAAG,MAAwB,CAAA;IACnC,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,CAAC,OAAO,KAAK,UAAU;QAAE,OAAO,IAAI,CAAA;IACxD,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,gBAAgB,GAAG,CAAC,CAAA;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAe;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,SAAS,GAAG,CAAC,CAAA;IAC5C,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,MAAM,CAAA;IACnD,GAAG,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;IACxD,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;IAC7D,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,iBAAiB,CAAA;IACnE,OAAO,IAAI,CAAA;AACZ,CAAC"}
@@ -148,6 +148,15 @@ export interface RenderCertBlockInput {
148
148
  * Ignored outside banner mode.
149
149
  */
150
150
  readonly part?: 'full' | 'header' | 'memo';
151
+ /**
152
+ * 1.1.0: the PHONE face. ABSENT ⇒ byte-identical to 1.0.3. `true` ⇒ at `NARROW_VIEWPORT` or
153
+ * narrower the banner header stacks its author and reviewer columns, and a long memo
154
+ * (`memoCollapses`) is clamped to `MEMO_COLLAPSED_LINES` lines behind a native toggle
155
+ * (`memo-toggle.ts`) on every face that paints one. Wider viewports paint the same card as
156
+ * without it. The Builder card's envelope face sets it; the options path and every other
157
+ * surface leave it off.
158
+ */
159
+ readonly responsive?: boolean;
151
160
  }
152
161
  /**
153
162
  * Render the LOCKED CertREV cert design as an SSR-safe HTML string for one placement
@@ -1 +1 @@
1
- {"version":3,"file":"render-cert-block.d.ts","sourceRoot":"","sources":["../../src/components/render-cert-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAKH,OAAO,EAMN,KAAK,kBAAkB,EAEvB,MAAM,iBAAiB,CAAA;AAExB,wCAAwC;AACxC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE7D,0GAA0G;AAC1G,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,QAAQ,CAAA;AAEtD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CACxC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,qEAAqE;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAA;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,oFAAoF;IACpF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACxC;AAED,2CAA2C;AAC3C,MAAM,WAAW,oBAAoB;IACpC,oFAAoF;IACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAA;IAC/B,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;IAC9B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;CAC1C;AAikBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAsCnE"}
1
+ {"version":3,"file":"render-cert-block.d.ts","sourceRoot":"","sources":["../../src/components/render-cert-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAcH,OAAO,EAMN,KAAK,kBAAkB,EAEvB,MAAM,iBAAiB,CAAA;AAExB,wCAAwC;AACxC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE7D,0GAA0G;AAC1G,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,QAAQ,CAAA;AAEtD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CACxC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,qEAAqE;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAA;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,oFAAoF;IACpF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACxC;AAED,2CAA2C;AAC3C,MAAM,WAAW,oBAAoB;IACpC,oFAAoF;IACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAA;IAC/B,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;IAC9B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;IAC1C;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAC7B;AA6oBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAwCnE"}