@nextcommerce/campaigns-os 1.43.2 → 1.47.0

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 (80) hide show
  1. package/AGENTS.md +5 -0
  2. package/CHANGELOG.md +798 -5103
  3. package/README.md +33 -12
  4. package/agents/claude/CLAUDE.md +1 -1
  5. package/agents/codex/AGENTS.md +1 -1
  6. package/agents/copilot/copilot-instructions.md +1 -1
  7. package/agents/cursor/campaigns-os.mdc +1 -1
  8. package/campaign-spec/dist/rules/analytics-contract-shape.d.ts +2 -2
  9. package/campaign-spec/dist/rules/analytics-contract-shape.js +2 -2
  10. package/campaign-spec/dist/rules/store-profile-shape.d.ts +5 -1
  11. package/campaign-spec/dist/rules/store-profile-shape.js +8 -10
  12. package/campaign-spec/dist/types.d.ts +2 -2
  13. package/compatibility.json +1 -1
  14. package/contracts/archive/CHANGELOG.2026-09-30.md +5111 -0
  15. package/contracts/archive/release-ledger.2026-09-30.json +5068 -0
  16. package/contracts/commerce-surface-catalog.json +1204 -129
  17. package/contracts/effects.v1.json +1179 -116
  18. package/contracts/orientation-reason-codes.v1.json +7 -0
  19. package/contracts/release-ledger.json +2515 -5919
  20. package/contracts/supported-surface.json +7 -4
  21. package/contracts/template-brand-contract.shared-commerce.v0.json +3 -3
  22. package/contracts/template-slot-manifest.shared-content-core.v0.json +403 -0
  23. package/docs/brand-theme-bridge.md +81 -0
  24. package/docs/build-packet.md +180 -23
  25. package/docs/campaigns-os-build-flow.md +3 -3
  26. package/docs/design-source-package.md +73 -0
  27. package/docs/effects.md +50 -8
  28. package/docs/gateway-login.md +3 -0
  29. package/docs/local-setup.md +7 -4
  30. package/docs/orientation-contract-reference.md +42 -2
  31. package/docs/polish-evidence.md +74 -0
  32. package/docs/qa-and-test-orders.md +118 -14
  33. package/docs/release-ledger-authoring-guide.md +64 -4
  34. package/docs/runtime-readiness.md +1 -1
  35. package/docs/sdk-storage-compatibility.md +1 -1
  36. package/docs/skills-revision.md +10 -10
  37. package/docs/supported-surface.md +2 -2
  38. package/docs/versioning.md +4 -1
  39. package/package.json +1 -1
  40. package/schemas/campaigns-os-release-ledger.v1.schema.json +32 -2
  41. package/schemas/campaigns-os-tooling-orientation.v1.schema.json +1 -0
  42. package/skills/campaign-lifecycle-orientation/SKILL.md +16 -5
  43. package/skills/campaign-readback-classification/SKILL.md +3 -3
  44. package/skills/campaign-run-evidence/SKILL.md +7 -6
  45. package/skills/contribution-intake/SKILL.md +3 -3
  46. package/skills/next-campaigns-build/SKILL.md +7 -6
  47. package/skills/next-campaigns-os/SKILL.md +7 -7
  48. package/skills/next-campaigns-os/references/session-intake.md +9 -3
  49. package/skills/next-campaigns-os-setup/SKILL.md +5 -5
  50. package/skills/next-campaigns-polish/SKILL.md +28 -9
  51. package/skills/next-campaigns-qa/SKILL.md +7 -4
  52. package/skills.json +10 -10
  53. package/src/brand-theme.mjs +320 -20
  54. package/src/built-script-syntax.mjs +116 -15
  55. package/src/built-site-scope.mjs +16 -4
  56. package/src/cli.mjs +280 -46
  57. package/src/commercial-parity.mjs +48 -2
  58. package/src/deviation.mjs +13 -1
  59. package/src/diagnostic.mjs +6 -2
  60. package/src/doctor/checks.mjs +319 -81
  61. package/src/doctor/inspect.mjs +55 -13
  62. package/src/doctor/source-provenance.mjs +184 -0
  63. package/src/invocation.mjs +4 -0
  64. package/src/live-campaign-refs.mjs +466 -0
  65. package/src/login.mjs +2 -2
  66. package/src/page-kit-store-profile.mjs +69 -12
  67. package/src/page-kit-sync.mjs +31 -12
  68. package/src/progress-node.mjs +3 -1
  69. package/src/qa-analytics-parity.mjs +37 -2
  70. package/src/qa-binding-evidence.mjs +4 -2
  71. package/src/qa-browser.mjs +612 -40
  72. package/src/qa-commercial-parity.mjs +48 -5
  73. package/src/qa-node.mjs +122 -7
  74. package/src/qa-test-order-topology.mjs +148 -0
  75. package/src/sdk-markup.mjs +32 -7
  76. package/src/sdk-storage-compatibility.mjs +3 -2
  77. package/src/source-html-intake.mjs +116 -0
  78. package/src/stage-record.mjs +551 -0
  79. package/src/tooling-setup.mjs +9 -0
  80. package/src/upsell-selector-scope.mjs +112 -2
@@ -168,13 +168,44 @@
168
168
  "accept_text",
169
169
  "decline_text",
170
170
  "retail_shipping",
171
- "offer_shipping"
171
+ "offer_shipping",
172
+ "type",
173
+ "display_selector_id",
174
+ "display_bundle_id",
175
+ "voucher",
176
+ "pricing_mode",
177
+ "pretitle",
178
+ "title",
179
+ "rating_text",
180
+ "heading_prices",
181
+ "quantity_label",
182
+ "accept_show_price",
183
+ "cta_note",
184
+ "ships_info_text",
185
+ "social_proof",
186
+ "urgency_text",
187
+ "image",
188
+ "closing_title",
189
+ "default_quantity",
190
+ "min_quantity",
191
+ "max_quantity",
192
+ "tier_count",
193
+ "variant_labels",
194
+ "price_rows",
195
+ "show_rating",
196
+ "retail_label",
197
+ "price_label",
198
+ "unit_label",
199
+ "total_label",
200
+ "details_hint",
201
+ "image_alt",
202
+ "image_display"
172
203
  ],
173
204
  "sourceOfTruth": [
174
205
  "CampaignSpec upsell/downsell pages",
175
206
  "Campaigns API package refs and vouchers/offers"
176
207
  ],
177
- "agentRule": "Post-purchase upsells do not use shipping_methods. Package refs and vouchers must come from the upsell page contract. `retail_shipping` and `offer_shipping` are display copy for the offer price block (the struck retail shipping line and the offer shipping line), not shipping method refs. The starter defaults claim `+$4.95 SHIPPING` and `+ FREE SHIPPING`; set both from the target campaign's real shipping figures whenever they differ."
208
+ "agentRule": "Post-purchase upsells do not use shipping_methods. Package refs and vouchers must come from the upsell page contract. `retail_shipping` and `offer_shipping` are display copy for the offer price block (the struck retail shipping line and the offer shipping line), not shipping method refs. The starter defaults claim `+$4.95 SHIPPING` and `+ FREE SHIPPING`; set both from the target campaign's real shipping figures whenever they differ.Upsell pricing_mode defaults to full_price (one visible price row) per template-brand-contract.shared-commerce.v0; set discounted / compare_at explicitly when an offer or voucher governs the price. Copy keys (pretitle, title, rating_text, cta_note, …) are display strings — HTML allowed, data-next-display spans allowed — never package refs."
178
209
  },
179
210
  "upsell_bundle_tiers": {
180
211
  "purpose": "Tiered post-purchase bundle upsell rows.",
@@ -226,13 +257,29 @@
226
257
  "show_paypal",
227
258
  "show_klarna",
228
259
  "show_apple_pay",
229
- "show_google_pay"
260
+ "show_google_pay",
261
+ "show_link",
262
+ "show_affirm",
263
+ "show_twint",
264
+ "show_bancontact",
265
+ "show_ideal",
266
+ "show_sepa_debit",
267
+ "style",
268
+ "secure_text",
269
+ "show_visa",
270
+ "show_mastercard",
271
+ "show_american_express",
272
+ "show_discover",
273
+ "show_diners_club",
274
+ "show_jcb",
275
+ "show_maestro",
276
+ "show_dankort"
230
277
  ],
231
278
  "sourceOfTruth": [
232
279
  "CampaignSpec payment methods",
233
280
  "Campaigns API/payment provider capability"
234
281
  ],
235
- "agentRule": "Payment config, CampaignSpec/API support, and visible rows must agree."
282
+ "agentRule": "Payment config, CampaignSpec/API support, and visible rows must agree. On upsell and checkout pages the logo row resolves itself from next.getCampaignData() (available_payment_methods + available_express_payment_methods, platform payment-source codes); payment_flags.show_<code> is only a per-method override. Card brands: the platform exposes cards as the single code bankcard and the merchant's gateway accepted_card_types list (visa, mastercard, american_express, discover, diners_club, jcb, maestro, dankort; empty = all) is NOT in the campaign payload, so bankcard shows the four common tiles by default; the other four are opt-in (show_jcb: true) and any brand can be forced off (show_american_express: false). Use the platform codes, not abbreviations."
236
283
  },
237
284
  "slot_personalization": {
238
285
  "purpose": "MV slot-picker line-item personalization (SDK 0.4.27+). Adds a data-next-property input to each rendered bundle slot — on the checkout/select selector AND the post-purchase upsell offer — so units carry distinct text and become separate order lines. Same contract name across both surfaces.",
@@ -246,7 +293,7 @@
246
293
  ],
247
294
  "sourceOfTruth": [
248
295
  "Campaign personalization requirement (per-line custom text)",
249
- "Template slot partials: mv-configurable-selector.html / mv-slot-stage.html (checkout/select) and upsell-mv-offer.html (upsell)"
296
+ "Template slot partials: mv-configurable-selector.html / mv-slot-stage.html (checkout/select) and upsell/offer-selector.html (MV upsell slot template)"
250
297
  ],
251
298
  "agentRule": "MV/slot-rendering families only — per-line customization requires a slot picker (eng-confirmed); not available on tier-swap families. Same `slot_personalization` contract on MV checkout/select and MV upsell. Shipped enabled on `apollo-mv-single-step` and `olympus-mv-single-step` (checkout.html + upsell-mv.html), disabled on `olympus-mv-two-step` (one live reference each). To apply on any other MV page, set slot_personalization.enabled:true in that page's frontmatter — the shared partial renders the field from the same contract (no markup copy). property_key becomes the order line-item attribute name. Fill every slot explicitly; do not rely on an order-wide default to fill some slots and override others (same-package overrides drop). When paired with order_personalization, keep property_keys distinct (per-slot overrides the page default on a shared key)."
252
299
  },
@@ -265,6 +312,206 @@
265
312
  "Template partial: personalization-field.html; offer partials may render the same order_personalization contract with data-next-default-property"
266
313
  ],
267
314
  "agentRule": "Reliable for 'same value on every unit' and for single non-variant / non-slot upsells where the accepted set is one line. The generic partial ships in every family's _includes but is NOT wired into generic pages; opt in with a campaign_include or an offer partial that accepts order_personalization. For per-line distinct slot values use slot_personalization (MV checkout/select/upsell) instead. When paired with a per-slot field on the same surface, use a DISTINCT property_key: the merge is { ...default, ...slot } so a per-slot value overrides the default on a shared key (MV checkout uses custom_text vs slot number; MV upsell example uses gift_message vs slot upsell_message)."
315
+ },
316
+ "upsell_layout": {
317
+ "purpose": "Layout knobs for the composable upsell/offer.html shell.",
318
+ "canonicalKeys": [
319
+ "boxed",
320
+ "media",
321
+ "media_position",
322
+ "show_bullets",
323
+ "show_ships_info",
324
+ "show_payment_logos",
325
+ "media_align",
326
+ "media_width",
327
+ "style",
328
+ "decline_position",
329
+ "show_decline"
330
+ ],
331
+ "sourceOfTruth": [
332
+ "CampaignSpec upsell page copy / design spec"
333
+ ],
334
+ "agentRule": "media: carousel|image|grid|video|none (the swiper area; video reads media_video, same contract as upsell_video — upsell_video itself is the content-column include under the heading); media_position: right (default, content left) | left; boxed false + upsell_hero.variant card is the long-form (VSL) look. Pure presentation — never derived from the API."
335
+ },
336
+ "upsell_hero": {
337
+ "purpose": "Upsell title band (band) or band + overlapping offer card with countdown (card).",
338
+ "canonicalKeys": [
339
+ "variant",
340
+ "title",
341
+ "offer",
342
+ "suboffer",
343
+ "heading",
344
+ "text",
345
+ "narrow"
346
+ ],
347
+ "sourceOfTruth": [
348
+ "CampaignSpec upsell page copy / design spec"
349
+ ],
350
+ "agentRule": "HTML strings; quote SDK values with data-next-display spans (bundle.upsell-bundle-1x.* for the pinned 1× price on tier offers, bundle.<selector_id>.* on stepper/single-with-voucher, package.<id>.name everywhere)."
351
+ },
352
+ "upsell_video": {
353
+ "purpose": "VSL / product video rendered by upsell/video.html (native <video>).",
354
+ "canonicalKeys": [
355
+ "src",
356
+ "poster",
357
+ "title",
358
+ "autoplay",
359
+ "loop",
360
+ "controls",
361
+ "preload",
362
+ "id"
363
+ ],
364
+ "sourceOfTruth": [
365
+ "CampaignSpec upsell page copy / design spec"
366
+ ],
367
+ "agentRule": "src is a local asset path or an https URL — NEXT-hosted media MUST use cdn.cachebucket.com. autoplay defaults true and always pairs with muted (browser policy). Rendered under the offer heading whenever set; independent of upsell_layout.media. No player library. preload defaults metadata (autoplay) / none (autoplay: false). The <video> carries data-upsell-video (+ optional id) as the hook for a campaign-supplied player script; set controls: false when layering one on."
368
+ },
369
+ "upsell_guarantees": {
370
+ "purpose": "Trust / guarantee cards under the accept button.",
371
+ "canonicalKeys": [
372
+ "variant",
373
+ "icon",
374
+ "image",
375
+ "title",
376
+ "text"
377
+ ],
378
+ "sourceOfTruth": [
379
+ "CampaignSpec upsell page copy / design spec"
380
+ ],
381
+ "agentRule": "variant stacked (centered icon + title + text) | row (badge left, \"<strong>title</strong> text\" right). Guarantee copy must match the store policy links in campaigns.json."
382
+ },
383
+ "upsell_body": {
384
+ "purpose": "Ordered long-form sections between the offer and the closing CTA.",
385
+ "canonicalKeys": [
386
+ "type",
387
+ "title",
388
+ "text",
389
+ "items",
390
+ "steps",
391
+ "with",
392
+ "without",
393
+ "rating_text",
394
+ "recommended_label"
395
+ ],
396
+ "sourceOfTruth": [
397
+ "CampaignSpec upsell page copy / design spec"
398
+ ],
399
+ "agentRule": "type reviews | features | comparison | steps. Section copy is design-owned; any price/percentage inside it is a data-next-display span, never a literal."
400
+ },
401
+ "closing_cta": {
402
+ "purpose": "Closing CTA block after the body sections.",
403
+ "canonicalKeys": [
404
+ "variant",
405
+ "title",
406
+ "note",
407
+ "image",
408
+ "background",
409
+ "show_guarantees"
410
+ ],
411
+ "sourceOfTruth": [
412
+ "CampaignSpec upsell page copy / design spec"
413
+ ],
414
+ "agentRule": "variant cta (centered button + note + decline) | card (boxed image + price rows + button + decline). Its accept/skip are data-upsell-proxy buttons forwarded to the single in-offer SDK action — never add a second data-next-upsell=\"offer\" wrapper."
415
+ },
416
+ "offer_bullets": {
417
+ "purpose": "Feature bullets in the upsell offer content column.",
418
+ "canonicalKeys": [
419
+ "text"
420
+ ],
421
+ "sourceOfTruth": [
422
+ "CampaignSpec upsell page copy / design spec"
423
+ ],
424
+ "agentRule": "Array of strings or { text }. Absent = demo bullets render; upsell_layout.show_bullets false removes the block."
425
+ },
426
+ "ships_info": {
427
+ "purpose": "Shipping reassurance row under the upsell accept button.",
428
+ "canonicalKeys": [
429
+ "icon",
430
+ "flag",
431
+ "text"
432
+ ],
433
+ "sourceOfTruth": [
434
+ "Store shipping policy / fulfilment facts"
435
+ ],
436
+ "agentRule": "text is HTML with a {flag} token for the inline flag image; the defaults claim USPS from the USA within 1 business day — replace with the merchant's real carrier and origin, or set upsell_layout.show_ships_info: false."
437
+ },
438
+ "swiper_gallery": {
439
+ "purpose": "Carousel media for checkout and upsell pages (swiper-gallery.html).",
440
+ "canonicalKeys": [
441
+ "swiper_slides",
442
+ "swiper_thumbs",
443
+ "swiper_aspect",
444
+ "swiper_thumb_aspect",
445
+ "swiper_fit",
446
+ "swiper_thumbs_per_view"
447
+ ],
448
+ "sourceOfTruth": [
449
+ "Campaign product images / design spec"
450
+ ],
451
+ "agentRule": "swiper_slides / swiper_thumbs are { src, alt } lists; aspect 16-9 | 3-2 | 4-3 (default square); fit contain | cover; swiper_thumbs_per_view default 6. Requires the Swiper CDN CSS + JS in the page styles: / scripts:."
452
+ },
453
+ "media_images": {
454
+ "purpose": "2×2 image grid for upsell_layout.media: grid.",
455
+ "canonicalKeys": [
456
+ "src",
457
+ "alt"
458
+ ],
459
+ "sourceOfTruth": [
460
+ "Campaign product images"
461
+ ],
462
+ "agentRule": "Four { src, alt } entries; used only when upsell_layout.media is grid."
463
+ },
464
+ "media_video": {
465
+ "purpose": "Video in the upsell media column (upsell_layout.media: video).",
466
+ "canonicalKeys": [
467
+ "src",
468
+ "poster",
469
+ "title",
470
+ "autoplay",
471
+ "loop",
472
+ "controls",
473
+ "preload",
474
+ "id"
475
+ ],
476
+ "sourceOfTruth": [
477
+ "Campaign media on cdn.cachebucket.com"
478
+ ],
479
+ "agentRule": "Same contract as upsell_video; independent of it so a page can carry a content-column VSL and a media-column video."
480
+ },
481
+ "header_bar": {
482
+ "purpose": "Upsell top bar variant.",
483
+ "canonicalKeys": [
484
+ "header_bar"
485
+ ],
486
+ "sourceOfTruth": [
487
+ "Design spec"
488
+ ],
489
+ "agentRule": "steps (logo + Checkout › Upgrades › Summary) | logo (centered logo only)."
490
+ },
491
+ "announcement": {
492
+ "purpose": "Upsell top announcement bar.",
493
+ "canonicalKeys": [
494
+ "announcement_text",
495
+ "announcement_variant"
496
+ ],
497
+ "sourceOfTruth": [
498
+ "Design spec / campaign copy"
499
+ ],
500
+ "agentRule": "announcement_variant primary (default) | danger | success | dark | light; absent or \"\" text renders nothing."
501
+ },
502
+ "countdown_timer": {
503
+ "purpose": "Slim urgency bar + countdown (countdown-timer.html), used on checkout, upsells and inside the upsell hero card.",
504
+ "canonicalKeys": [
505
+ "text",
506
+ "highlight",
507
+ "duration",
508
+ "persistence_id",
509
+ "start"
510
+ ],
511
+ "sourceOfTruth": [
512
+ "Campaign offer rules / design spec"
513
+ ],
514
+ "agentRule": "duration (seconds) renders the SDK data-next-timer persisted per persistence_id — give each offer its own id; start (\"MM:SS\") is the legacy checkout.js-driven mode. Absent = nothing renders."
268
515
  }
269
516
  },
270
517
  "campaignSpecFixturePolicy": {
@@ -291,7 +538,8 @@
291
538
  "olympus in spec, path, or export metadata",
292
539
  "os-card tier bundle selector",
293
540
  "bundle selector include receives bundles frontmatter",
294
- "side cart summary with Olympus card pricing rows"
541
+ "side cart summary with Olympus card pricing rows",
542
+ "upsell-single page (single-offer add-on: one package, fixed price, accept or skip)"
295
543
  ],
296
544
  "canonicalSurfaces": {
297
545
  "mainSelector": "tiered-bundle-selector",
@@ -299,7 +547,7 @@
299
547
  "payment": "payment-methods",
300
548
  "expressCheckout": "express-checkout|express-checkout-inline",
301
549
  "orderBump": "bump-check01|bump-check02|bump-check03|bump-switch01",
302
- "upsell": "bundle-stepper|bundle-tier-pills|bundle-tier-cards",
550
+ "upsell": "bundle-stepper|bundle-tier-pills|bundle-tier-cards|single (+ vsl page) — all via the shared upsell/offer.html shell (upsell_offer.type)",
303
551
  "receipt": "receipt-skeleton"
304
552
  },
305
553
  "frontmatterInputsObserved": [
@@ -312,7 +560,22 @@
312
560
  "swiper_slides",
313
561
  "swiper_thumbs",
314
562
  "upsell_offer",
315
- "upsell_bundle_tiers"
563
+ "upsell_bundle_tiers",
564
+ "offer_features",
565
+ "offer_comparison",
566
+ "offer_steps",
567
+ "guarantee_note",
568
+ "countdown_timer",
569
+ "announcement_text",
570
+ "upsell_layout",
571
+ "upsell_hero",
572
+ "offer_bullets",
573
+ "upsell_video",
574
+ "upsell_guarantees",
575
+ "upsell_body",
576
+ "closing_cta",
577
+ "ships_info",
578
+ "payment_flags"
316
579
  ],
317
580
  "agentContract": {
318
581
  "status": "agent-ready",
@@ -430,19 +693,109 @@
430
693
  {
431
694
  "name": "Olympus bundle upsell pages",
432
695
  "partials": [
433
- "upsell-bundle-stepper-offer.html",
434
- "upsell-bundle-tier-pills-offer.html",
435
- "upsell-bundle-tier-cards-offer.html"
696
+ "upsell/offer.html",
697
+ "upsell/offer-context.html",
698
+ "upsell/offer-tier.html",
699
+ "upsell/offer-selector.html",
700
+ "upsell/offer-controls.html",
701
+ "upsell/offer-heading.html",
702
+ "upsell/offer-bullets.html",
703
+ "upsell/offer-prices.html",
704
+ "upsell/offer-media.html",
705
+ "upsell/cta.html",
706
+ "upsell/decline.html",
707
+ "upsell/ships-info.html",
708
+ "upsell/video.html",
709
+ "upsell/guarantees.html",
710
+ "upsell/copy.html",
711
+ "payment-logos.html (shared with checkout)",
712
+ "upsell/announcement.html",
713
+ "upsell/header-bar.html",
714
+ "upsell/hero.html",
715
+ "upsell/body.html",
716
+ "upsell/reviews.html",
717
+ "upsell/features.html",
718
+ "upsell/comparison.html",
719
+ "upsell/steps.html",
720
+ "upsell/closing-cta.html"
436
721
  ],
437
722
  "ownedInputs": [
723
+ "announcement_text",
724
+ "closing_cta",
725
+ "countdown_timer",
726
+ "offer_bullets",
727
+ "payment_flags",
728
+ "ships_info",
729
+ "upsell_body",
730
+ "upsell_bundle_tiers",
731
+ "upsell_guarantees",
732
+ "upsell_hero",
733
+ "upsell_layout",
438
734
  "upsell_offer",
439
- "upsell_bundle_tiers"
735
+ "upsell_video"
440
736
  ],
441
737
  "sdkRoots": [
442
738
  "data-next-upsell",
443
739
  "data-next-bundle-selector",
444
740
  "data-next-bundle-card"
445
- ]
741
+ ],
742
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note)."
743
+ },
744
+ {
745
+ "name": "Olympus single-offer upsell page",
746
+ "partials": [
747
+ "upsell/offer.html",
748
+ "upsell/offer-context.html",
749
+ "upsell/offer-tier.html",
750
+ "upsell/offer-selector.html",
751
+ "upsell/offer-controls.html",
752
+ "upsell/offer-heading.html",
753
+ "upsell/offer-bullets.html",
754
+ "upsell/offer-prices.html",
755
+ "upsell/offer-media.html",
756
+ "upsell/cta.html",
757
+ "upsell/decline.html",
758
+ "upsell/ships-info.html",
759
+ "upsell/video.html",
760
+ "upsell/guarantees.html",
761
+ "upsell/copy.html",
762
+ "payment-logos.html (shared with checkout)",
763
+ "upsell/announcement.html",
764
+ "upsell/header-bar.html",
765
+ "upsell/hero.html",
766
+ "upsell/body.html",
767
+ "upsell/reviews.html",
768
+ "upsell/features.html",
769
+ "upsell/comparison.html",
770
+ "upsell/steps.html",
771
+ "upsell/closing-cta.html"
772
+ ],
773
+ "ownedInputs": [
774
+ "announcement_text",
775
+ "closing_cta",
776
+ "countdown_timer",
777
+ "guarantee_note",
778
+ "offer_bullets",
779
+ "offer_comparison",
780
+ "offer_features",
781
+ "offer_steps",
782
+ "payment_flags",
783
+ "ships_info",
784
+ "upsell_body",
785
+ "upsell_bundle_tiers",
786
+ "upsell_guarantees",
787
+ "upsell_hero",
788
+ "upsell_layout",
789
+ "upsell_offer",
790
+ "upsell_video"
791
+ ],
792
+ "sdkRoots": [
793
+ "data-next-upsell",
794
+ "data-next-bundle-selector",
795
+ "data-next-bundle-card",
796
+ "data-next-timer"
797
+ ],
798
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note)."
446
799
  }
447
800
  ],
448
801
  "fixtures": [
@@ -495,9 +848,9 @@
495
848
  }
496
849
  },
497
850
  "verification": {
498
- "sdk_version": "0.4.38",
499
- "verified_at": "2026-09-15T16:51:10Z",
500
- "evidence": "sdk-0.4.38-2026-09-15",
851
+ "sdk_version": "0.4.40",
852
+ "verified_at": "2026-10-01T04:56:01Z",
853
+ "evidence": "sdk-0.4.40-2026-10-01",
501
854
  "status": "certified",
502
855
  "source": "template-verification.json"
503
856
  }
@@ -507,8 +860,8 @@
507
860
  "templateReference": {
508
861
  "id": "template-reference-apollo",
509
862
  "family": "apollo",
510
- "version": "sdk-0.4.38-revalidated-2026-09-03",
511
- "source_commit": "84a63fe7af8cf49cd8cfdaaa66eb00ef6dd9bc4a",
863
+ "version": "sdk-0.4.38-composable-upsells-2026-09-25",
864
+ "source_commit": "6c96525b6416872ad0e51918fe6ec82a9673808c",
512
865
  "provenance_url": "https://raw.githubusercontent.com/NextCommerceCo/campaign-cart-starter-templates/main/docs/template-references/apollo/README.md",
513
866
  "contract_path": "contracts/commerce-surface-catalog.json",
514
867
  "standard_viewport_refs": [
@@ -518,21 +871,21 @@
518
871
  "url": "https://raw.githubusercontent.com/NextCommerceCo/campaign-cart-starter-templates/main/docs/template-references/apollo/checkout-desktop.png",
519
872
  "width": 1440,
520
873
  "height": 1491,
521
- "sha256": "e0fd4854422b9ca90b54adc1477e1291824fc63e898e50c5c6cc8e4e58ce39e6",
874
+ "sha256": "7595630f9e3dd4da09c395f7681c1ff546011141d3981412d5f76a1ffe2d5c90",
522
875
  "device_profile": "Desktop 1440",
523
876
  "browser": "chromium",
524
- "captured_at": "2026-08-24T05:10:18.000Z"
877
+ "captured_at": "2026-09-25T00:10:12.000Z"
525
878
  },
526
879
  {
527
880
  "id": "apollo-checkout-mobile",
528
881
  "viewport": "mobile",
529
882
  "url": "https://raw.githubusercontent.com/NextCommerceCo/campaign-cart-starter-templates/main/docs/template-references/apollo/checkout-mobile.png",
530
883
  "width": 390,
531
- "height": 2650,
532
- "sha256": "14386e851e70b21f03ac2608c1efcde18b2bfc4d31736cb07add199e1953fe5c",
884
+ "height": 2648,
885
+ "sha256": "1d797be266beefb10cf7ec4502d8f8c97286a0861b969695986ebfc1ac29ce63",
533
886
  "device_profile": "Mobile 390",
534
887
  "browser": "chromium",
535
- "captured_at": "2026-08-24T05:10:23.000Z"
888
+ "captured_at": "2026-09-25T00:10:12.000Z"
536
889
  }
537
890
  ]
538
891
  },
@@ -542,9 +895,11 @@
542
895
  "checkout-apollo.js",
543
896
  "bundle_card_style frontmatter",
544
897
  "bundle-selector.html with bundle-card dispatcher",
545
- "promo-banner and promo-timer partials (not web components)",
898
+ "promo-banner and countdown-timer partials (not web components)",
546
899
  "checkout-reveal CTA and panel",
547
- "selector_order_bump_variant for check03 below selector"
900
+ "selector_order_bump_variant for check03 below selector",
901
+ "upsell-single page (single-offer add-on: one package, fixed price, accept or skip)",
902
+ "upsell-vsl page (long-form VSL upsell composed from the shared upsell partial set: hero card + countdown, video under the heading, guarantees, reviews, closing CTA)"
548
903
  ],
549
904
  "canonicalSurfaces": {
550
905
  "mainSelector": "tiered-bundle-selector",
@@ -555,7 +910,7 @@
555
910
  "expressCheckout": "express-checkout|express-checkout-inline",
556
911
  "orderBump": "bump-check01|bump-check02|bump-check03|bump-switch01",
557
912
  "checkoutReveal": "checkout-form--reveal",
558
- "upsell": "bundle-stepper|bundle-tier-pills|bundle-tier-cards",
913
+ "upsell": "bundle-stepper|bundle-tier-pills|bundle-tier-cards|single (+ vsl page = stepper offer_type in the long-form composition)",
559
914
  "receipt": "receipt-skeleton"
560
915
  },
561
916
  "frontmatterInputsObserved": [
@@ -570,7 +925,7 @@
570
925
  "as_seen_in",
571
926
  "reviews_slider",
572
927
  "guarantee",
573
- "promo_timer",
928
+ "countdown_timer",
574
929
  "promo_banner",
575
930
  "product_heading",
576
931
  "packages",
@@ -578,7 +933,16 @@
578
933
  "swiper_slides",
579
934
  "swiper_thumbs",
580
935
  "upsell_offer",
581
- "upsell_bundle_tiers"
936
+ "upsell_bundle_tiers",
937
+ "upsell_hero",
938
+ "upsell_layout",
939
+ "offer_bullets",
940
+ "upsell_video",
941
+ "upsell_guarantees",
942
+ "upsell_body",
943
+ "closing_cta",
944
+ "header_bar",
945
+ "announcement_variant"
582
946
  ],
583
947
  "agentContract": {
584
948
  "status": "agent-ready",
@@ -622,7 +986,7 @@
622
986
  "reviews",
623
987
  "guarantee",
624
988
  "promo_banner",
625
- "promo_timer",
989
+ "countdown_timer",
626
990
  "product_heading",
627
991
  "packages.prepurchase_1",
628
992
  "packages.prepurchase_2",
@@ -630,7 +994,16 @@
630
994
  "swiper_thumbs",
631
995
  "payment_flags",
632
996
  "upsell_offer",
633
- "upsell_bundle_tiers"
997
+ "upsell_bundle_tiers",
998
+ "upsell_hero",
999
+ "upsell_layout",
1000
+ "offer_bullets",
1001
+ "upsell_video",
1002
+ "upsell_guarantees",
1003
+ "upsell_body",
1004
+ "closing_cta",
1005
+ "header_bar",
1006
+ "announcement_variant"
634
1007
  ],
635
1008
  "demoOnlyValues": [
636
1009
  "packages.main_package=1",
@@ -705,7 +1078,7 @@
705
1078
  "checkout-header.html",
706
1079
  "product-heading.html",
707
1080
  "promo-banner.html",
708
- "promo-timer.html",
1081
+ "countdown-timer.html",
709
1082
  "as-seen-in.html",
710
1083
  "reviews-slider.html",
711
1084
  "guarantee.html"
@@ -713,7 +1086,7 @@
713
1086
  "ownedInputs": [
714
1087
  "product_heading",
715
1088
  "promo_banner",
716
- "promo_timer",
1089
+ "countdown_timer",
717
1090
  "as_seen_in",
718
1091
  "reviews",
719
1092
  "guarantee"
@@ -754,7 +1127,8 @@
754
1127
  "name": "payment shell",
755
1128
  "partials": [
756
1129
  "payment-methods.html",
757
- "express-checkout.html"
1130
+ "express-checkout.html",
1131
+ "payment-logos.html"
758
1132
  ],
759
1133
  "ownedInputs": [
760
1134
  "payment_flags"
@@ -763,24 +1137,88 @@
763
1137
  "data-next-payment-method",
764
1138
  "data-next-payment-form",
765
1139
  "data-next-express-checkout"
766
- ]
1140
+ ],
1141
+ "note": "payment-logos.html under the submit button renders one logo per method; js/payment-logos.js reveals only those in the campaign's available_payment_methods (SDK sessionStorage cache first, then live)."
767
1142
  },
768
1143
  {
769
- "name": "Apollo bundle upsell pages",
1144
+ "name": "Apollo bundle upsell pages (composable upsell-offer shell)",
770
1145
  "partials": [
771
- "upsell-bundle-stepper-offer.html",
772
- "upsell-bundle-tier-pills-offer.html",
773
- "upsell-bundle-tier-cards-offer.html"
1146
+ "upsell/offer.html",
1147
+ "upsell/offer-context.html",
1148
+ "upsell/offer-tier.html",
1149
+ "upsell/offer-selector.html",
1150
+ "upsell/offer-controls.html",
1151
+ "upsell/offer-heading.html",
1152
+ "upsell/offer-bullets.html",
1153
+ "upsell/offer-prices.html",
1154
+ "upsell/offer-media.html",
1155
+ "upsell/cta.html",
1156
+ "upsell/decline.html",
1157
+ "upsell/video.html",
1158
+ "upsell/ships-info.html",
1159
+ "upsell/guarantees.html",
1160
+ "upsell/announcement.html",
1161
+ "upsell/header-bar.html",
1162
+ "upsell/hero.html",
1163
+ "upsell/body.html",
1164
+ "upsell/reviews.html",
1165
+ "upsell/features.html",
1166
+ "upsell/comparison.html",
1167
+ "upsell/steps.html",
1168
+ "upsell/closing-cta.html"
774
1169
  ],
775
1170
  "ownedInputs": [
776
1171
  "upsell_offer",
777
- "upsell_bundle_tiers"
1172
+ "upsell_bundle_tiers",
1173
+ "upsell_layout",
1174
+ "upsell_hero",
1175
+ "offer_bullets",
1176
+ "upsell_video",
1177
+ "upsell_guarantees",
1178
+ "upsell_body",
1179
+ "closing_cta",
1180
+ "announcement_text",
1181
+ "announcement_variant",
1182
+ "header_bar",
1183
+ "countdown_timer",
1184
+ "swiper_slides",
1185
+ "swiper_thumbs",
1186
+ "media_images",
1187
+ "ships_info",
1188
+ "payment_flags"
778
1189
  ],
779
1190
  "sdkRoots": [
780
1191
  "data-next-upsell",
781
1192
  "data-next-bundle-selector",
782
- "data-next-bundle-card"
783
- ]
1193
+ "data-next-bundle-card",
1194
+ "data-next-bundle-qty-for",
1195
+ "data-next-timer"
1196
+ ],
1197
+ "note": "Every upsell page composes the same partial set: upsell-announcement → upsell-header-bar (steps|logo) → upsell-hero (band|card) → countdown-timer → upsell-offer (the shell; offer_type tier-cards|tier-pills|stepper|single|mv picks the ONLY piece that differs, upsell/offer-controls.html + upsell/offer-selector.html) → upsell-body (reviews|features|comparison|steps sections) → upsell-closing-cta (cta|card) → footer. upsell/offer.html owns the single [data-next-upsell=\"offer\"] wrapper; the display-only 1x selector (tier-cards/tier-pills/mv) and the single-offer voucher selector sit outside it; the hidden state-machine selector is the first in-offer selector. upsell/offer-context.html resolves package_id / selector_id / price paths once (assign shares scope). upsell/closing-cta.html renders PROXY buttons (data-upsell-proxy=add|skip → initUpsellProxyActions() in upsells.js clicks the in-offer actions) so a page never has two SDK offer wrappers. pricing_mode (discounted|compare_at|full_price|unit_total|unit_only) lives in upsell/offer-prices.html; default full_price per the shared commerce contract, demo pages opt into discounted. upsell/video.html is a native <video> (autoplay+muted, controls) — no Plyr / custom controls; rendered under the heading whenever upsell_video is set (upsell_layout.media only picks the swiper-area content). Reference pages: upsell-bundle-stepper / -tier-pills / -tier-cards (classic band + boxed offer), upsell-single (offer + body sections + closing card), upsell-vsl (danger announcement bar, logo header, hero card + countdown, unboxed offer with video, guarantees, reviews, closing CTA). Identical set in all eight families, generated from _shared/upsell/ by sync-shared (lint:shared gate); MV families add upsell-mv.html with upsell_offer.type: mv. Switching upsell_offer.type alone renders a working selector: absent upsell_bundle_tiers / upsell_mv_tiers are generated from package_id (offer.tier_count, offer.vouchers_json) by upsell/offer-context.html + upsell/offer-tier.html; declare tiers only for distinct vouchers / labels."
1198
+ },
1199
+ {
1200
+ "name": "Apollo single-offer upsell page",
1201
+ "partials": [
1202
+ "upsell/offer.html (offer_type=single)",
1203
+ "upsell/body.html",
1204
+ "upsell/closing-cta.html (variant=card)"
1205
+ ],
1206
+ "ownedInputs": [
1207
+ "upsell_offer",
1208
+ "upsell_layout",
1209
+ "upsell_hero",
1210
+ "upsell_body",
1211
+ "closing_cta",
1212
+ "countdown_timer",
1213
+ "announcement_text"
1214
+ ],
1215
+ "sdkRoots": [
1216
+ "data-next-upsell",
1217
+ "data-next-bundle-selector",
1218
+ "data-next-bundle-card",
1219
+ "data-next-timer"
1220
+ ],
1221
+ "note": "Single-package, fixed-price offer (accept or skip, no tiers) — now offer_type='single' on the shared upsell/offer.html shell; the long-form sections are upsell_body entries (features, comparison, steps) and the closing card is upsell/closing-cta.html variant=card whose accept/skip are proxies to the one SDK offer. Optional `voucher` renders a hidden linked bundle selector outside the offer (data-next-bundle-selector-id on the wrapper) and prices read bundle.<selector_id>.*; without a voucher they read package.* gated on package.hasRetailPrice / hasSavings (data-next-show and data-next-display on separate elements). pricing_mode full_price (default) | discounted | compare_at | unit_total | unit_only. Countdown uses the SDK data-next-timer."
784
1222
  }
785
1223
  ],
786
1224
  "fixtures": [
@@ -834,9 +1272,9 @@
834
1272
  }
835
1273
  },
836
1274
  "verification": {
837
- "sdk_version": "0.4.38",
838
- "verified_at": "2026-09-15T16:51:10Z",
839
- "evidence": "sdk-0.4.38-2026-09-15",
1275
+ "sdk_version": "0.4.40",
1276
+ "verified_at": "2026-10-01T04:56:01Z",
1277
+ "evidence": "sdk-0.4.40-2026-10-01",
840
1278
  "status": "certified",
841
1279
  "source": "template-verification.json"
842
1280
  }
@@ -850,7 +1288,8 @@
850
1288
  "checkout-progress bar above bundle selection",
851
1289
  "open side cart using cart-summary03",
852
1290
  "luxury/editorial spacing with serif display type",
853
- "demeter upsell offer includes with upsell_offer or upsell_bundle_tiers frontmatter"
1291
+ "demeter upsell offer includes with upsell_offer or upsell_bundle_tiers frontmatter",
1292
+ "upsell-single page (single-offer add-on: one package, fixed price, accept or skip)"
854
1293
  ],
855
1294
  "canonicalSurfaces": {
856
1295
  "mainSelector": "editorial-tier-selector",
@@ -858,7 +1297,7 @@
858
1297
  "payment": "payment-methods",
859
1298
  "expressCheckout": "express-checkout|express-checkout-inline",
860
1299
  "orderBump": "bump-check01|bump-check02|bump-check03|bump-switch01",
861
- "upsell": "upsell-bundle-stepper-offer|upsell-bundle-tier-pills-offer|upsell-bundle-tier-cards-offer",
1300
+ "upsell": "bundle-stepper|bundle-tier-pills|bundle-tier-cards|single (+ vsl page) — all via the shared upsell/offer.html shell (upsell_offer.type)",
862
1301
  "receipt": "receipt-skeleton|receipt-order-summary-mobile|receipt-order-summary-desktop"
863
1302
  },
864
1303
  "frontmatterInputsNeeded": [
@@ -880,7 +1319,22 @@
880
1319
  "cart_summary_feature_package",
881
1320
  "receipt_summary",
882
1321
  "upsell_bundle_tiers",
883
- "upsell_offer"
1322
+ "upsell_offer",
1323
+ "offer_features",
1324
+ "offer_comparison",
1325
+ "offer_steps",
1326
+ "guarantee_note",
1327
+ "countdown_timer",
1328
+ "announcement_text",
1329
+ "upsell_layout",
1330
+ "upsell_hero",
1331
+ "offer_bullets",
1332
+ "upsell_video",
1333
+ "upsell_guarantees",
1334
+ "upsell_body",
1335
+ "closing_cta",
1336
+ "ships_info",
1337
+ "payment_flags"
884
1338
  ],
885
1339
  "agentContract": {
886
1340
  "status": "agent-ready",
@@ -975,20 +1429,109 @@
975
1429
  {
976
1430
  "name": "upsell and receipt includes",
977
1431
  "partials": [
978
- "upsell-bundle-stepper-offer.html",
979
- "upsell-bundle-tier-pills-offer.html",
980
- "upsell-bundle-tier-cards-offer.html",
981
- "receipt-skeleton.html"
1432
+ "upsell/offer.html",
1433
+ "upsell/offer-context.html",
1434
+ "upsell/offer-tier.html",
1435
+ "upsell/offer-selector.html",
1436
+ "upsell/offer-controls.html",
1437
+ "upsell/offer-heading.html",
1438
+ "upsell/offer-bullets.html",
1439
+ "upsell/offer-prices.html",
1440
+ "upsell/offer-media.html",
1441
+ "upsell/cta.html",
1442
+ "upsell/decline.html",
1443
+ "upsell/ships-info.html",
1444
+ "upsell/video.html",
1445
+ "upsell/guarantees.html",
1446
+ "upsell/copy.html",
1447
+ "payment-logos.html (shared with checkout)",
1448
+ "upsell/announcement.html",
1449
+ "upsell/header-bar.html",
1450
+ "upsell/hero.html",
1451
+ "upsell/body.html",
1452
+ "upsell/reviews.html",
1453
+ "upsell/features.html",
1454
+ "upsell/comparison.html",
1455
+ "upsell/steps.html",
1456
+ "upsell/closing-cta.html"
982
1457
  ],
983
1458
  "ownedInputs": [
984
- "upsell_offer",
1459
+ "announcement_text",
1460
+ "closing_cta",
1461
+ "countdown_timer",
1462
+ "offer_bullets",
1463
+ "payment_flags",
1464
+ "receipt_summary",
1465
+ "ships_info",
1466
+ "upsell_body",
985
1467
  "upsell_bundle_tiers",
986
- "receipt_summary"
1468
+ "upsell_guarantees",
1469
+ "upsell_hero",
1470
+ "upsell_layout",
1471
+ "upsell_offer",
1472
+ "upsell_video"
987
1473
  ],
988
1474
  "sdkRoots": [
989
1475
  "data-next-upsell",
990
1476
  "data-next-order-items"
991
- ]
1477
+ ],
1478
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note)."
1479
+ },
1480
+ {
1481
+ "name": "Demeter single-offer upsell page",
1482
+ "partials": [
1483
+ "upsell/offer.html",
1484
+ "upsell/offer-context.html",
1485
+ "upsell/offer-tier.html",
1486
+ "upsell/offer-selector.html",
1487
+ "upsell/offer-controls.html",
1488
+ "upsell/offer-heading.html",
1489
+ "upsell/offer-bullets.html",
1490
+ "upsell/offer-prices.html",
1491
+ "upsell/offer-media.html",
1492
+ "upsell/cta.html",
1493
+ "upsell/decline.html",
1494
+ "upsell/ships-info.html",
1495
+ "upsell/video.html",
1496
+ "upsell/guarantees.html",
1497
+ "upsell/copy.html",
1498
+ "payment-logos.html (shared with checkout)",
1499
+ "upsell/announcement.html",
1500
+ "upsell/header-bar.html",
1501
+ "upsell/hero.html",
1502
+ "upsell/body.html",
1503
+ "upsell/reviews.html",
1504
+ "upsell/features.html",
1505
+ "upsell/comparison.html",
1506
+ "upsell/steps.html",
1507
+ "upsell/closing-cta.html"
1508
+ ],
1509
+ "ownedInputs": [
1510
+ "announcement_text",
1511
+ "closing_cta",
1512
+ "countdown_timer",
1513
+ "guarantee_note",
1514
+ "offer_bullets",
1515
+ "offer_comparison",
1516
+ "offer_features",
1517
+ "offer_steps",
1518
+ "payment_flags",
1519
+ "ships_info",
1520
+ "upsell_body",
1521
+ "upsell_bundle_tiers",
1522
+ "upsell_guarantees",
1523
+ "upsell_hero",
1524
+ "upsell_layout",
1525
+ "upsell_offer",
1526
+ "upsell_video"
1527
+ ],
1528
+ "sdkRoots": [
1529
+ "data-next-upsell",
1530
+ "data-next-bundle-selector",
1531
+ "data-next-bundle-card",
1532
+ "data-next-timer"
1533
+ ],
1534
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note)."
992
1535
  }
993
1536
  ],
994
1537
  "fixtures": [
@@ -1040,9 +1583,9 @@
1040
1583
  }
1041
1584
  },
1042
1585
  "verification": {
1043
- "sdk_version": "0.4.38",
1044
- "verified_at": "2026-09-15T16:51:10Z",
1045
- "evidence": "sdk-0.4.38-2026-09-15",
1586
+ "sdk_version": "0.4.40",
1587
+ "verified_at": "2026-10-01T04:56:01Z",
1588
+ "evidence": "sdk-0.4.40-2026-10-01",
1046
1589
  "status": "certified",
1047
1590
  "source": "template-verification.json"
1048
1591
  }
@@ -1055,7 +1598,8 @@
1055
1598
  "shop checkout with checkout.html plus upsell-bundle-stepper/tier-pills/tier-cards pages",
1056
1599
  "cart-summary04 used on checkout",
1057
1600
  "receipt order summary split into mobile and desktop order item templates",
1058
- "upsell bundle offers promoted to shop-single-step *_offer includes"
1601
+ "upsell bundle offers promoted to shop-single-step *_offer includes",
1602
+ "upsell-single page (single-offer add-on: one package, fixed price, accept or skip)"
1059
1603
  ],
1060
1604
  "canonicalSurfaces": {
1061
1605
  "checkoutSummary": "cart-summary04",
@@ -1063,7 +1607,7 @@
1063
1607
  "expressCheckout": "express-checkout",
1064
1608
  "orderBump": "bump-check01|bump-check02|bump-check03|bump-switch01",
1065
1609
  "receipt": "receipt-skeleton|receipt-order-summary-mobile|receipt-order-summary-desktop",
1066
- "upsell": "upsell-bundle-stepper-offer|upsell-bundle-tier-pills-offer|upsell-bundle-tier-cards-offer"
1610
+ "upsell": "bundle-stepper|bundle-tier-pills|bundle-tier-cards|single (+ vsl page) — all via the shared upsell/offer.html shell (upsell_offer.type)"
1067
1611
  },
1068
1612
  "frontmatterInputsNeeded": [
1069
1613
  "cart_summary_variant"
@@ -1076,7 +1620,22 @@
1076
1620
  "swiper_slides",
1077
1621
  "swiper_thumbs",
1078
1622
  "upsell_bundle_tiers",
1079
- "upsell_offer"
1623
+ "upsell_offer",
1624
+ "offer_features",
1625
+ "offer_comparison",
1626
+ "offer_steps",
1627
+ "guarantee_note",
1628
+ "countdown_timer",
1629
+ "announcement_text",
1630
+ "upsell_layout",
1631
+ "upsell_hero",
1632
+ "offer_bullets",
1633
+ "upsell_video",
1634
+ "upsell_guarantees",
1635
+ "upsell_body",
1636
+ "closing_cta",
1637
+ "ships_info",
1638
+ "payment_flags"
1080
1639
  ],
1081
1640
  "agentContract": {
1082
1641
  "status": "agent-ready",
@@ -1160,18 +1719,52 @@
1160
1719
  {
1161
1720
  "name": "shop upsell offers",
1162
1721
  "partials": [
1163
- "upsell-bundle-stepper-offer.html",
1164
- "upsell-bundle-tier-pills-offer.html",
1165
- "upsell-bundle-tier-cards-offer.html"
1722
+ "upsell/offer.html",
1723
+ "upsell/offer-context.html",
1724
+ "upsell/offer-tier.html",
1725
+ "upsell/offer-selector.html",
1726
+ "upsell/offer-controls.html",
1727
+ "upsell/offer-heading.html",
1728
+ "upsell/offer-bullets.html",
1729
+ "upsell/offer-prices.html",
1730
+ "upsell/offer-media.html",
1731
+ "upsell/cta.html",
1732
+ "upsell/decline.html",
1733
+ "upsell/ships-info.html",
1734
+ "upsell/video.html",
1735
+ "upsell/guarantees.html",
1736
+ "upsell/copy.html",
1737
+ "payment-logos.html (shared with checkout)",
1738
+ "upsell/announcement.html",
1739
+ "upsell/header-bar.html",
1740
+ "upsell/hero.html",
1741
+ "upsell/body.html",
1742
+ "upsell/reviews.html",
1743
+ "upsell/features.html",
1744
+ "upsell/comparison.html",
1745
+ "upsell/steps.html",
1746
+ "upsell/closing-cta.html"
1166
1747
  ],
1167
1748
  "ownedInputs": [
1749
+ "announcement_text",
1750
+ "closing_cta",
1751
+ "countdown_timer",
1752
+ "offer_bullets",
1753
+ "payment_flags",
1754
+ "ships_info",
1755
+ "upsell_body",
1756
+ "upsell_bundle_tiers",
1757
+ "upsell_guarantees",
1758
+ "upsell_hero",
1759
+ "upsell_layout",
1168
1760
  "upsell_offer",
1169
- "upsell_bundle_tiers"
1761
+ "upsell_video"
1170
1762
  ],
1171
1763
  "sdkRoots": [
1172
1764
  "data-next-upsell",
1173
1765
  "data-next-bundle-selector"
1174
- ]
1766
+ ],
1767
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note)."
1175
1768
  },
1176
1769
  {
1177
1770
  "name": "shop receipt",
@@ -1186,6 +1779,62 @@
1186
1779
  "sdkRoots": [
1187
1780
  "data-next-order-items"
1188
1781
  ]
1782
+ },
1783
+ {
1784
+ "name": "Shop single-offer upsell page",
1785
+ "partials": [
1786
+ "upsell/offer.html",
1787
+ "upsell/offer-context.html",
1788
+ "upsell/offer-tier.html",
1789
+ "upsell/offer-selector.html",
1790
+ "upsell/offer-controls.html",
1791
+ "upsell/offer-heading.html",
1792
+ "upsell/offer-bullets.html",
1793
+ "upsell/offer-prices.html",
1794
+ "upsell/offer-media.html",
1795
+ "upsell/cta.html",
1796
+ "upsell/decline.html",
1797
+ "upsell/ships-info.html",
1798
+ "upsell/video.html",
1799
+ "upsell/guarantees.html",
1800
+ "upsell/copy.html",
1801
+ "payment-logos.html (shared with checkout)",
1802
+ "upsell/announcement.html",
1803
+ "upsell/header-bar.html",
1804
+ "upsell/hero.html",
1805
+ "upsell/body.html",
1806
+ "upsell/reviews.html",
1807
+ "upsell/features.html",
1808
+ "upsell/comparison.html",
1809
+ "upsell/steps.html",
1810
+ "upsell/closing-cta.html"
1811
+ ],
1812
+ "ownedInputs": [
1813
+ "announcement_text",
1814
+ "closing_cta",
1815
+ "countdown_timer",
1816
+ "guarantee_note",
1817
+ "offer_bullets",
1818
+ "offer_comparison",
1819
+ "offer_features",
1820
+ "offer_steps",
1821
+ "payment_flags",
1822
+ "ships_info",
1823
+ "upsell_body",
1824
+ "upsell_bundle_tiers",
1825
+ "upsell_guarantees",
1826
+ "upsell_hero",
1827
+ "upsell_layout",
1828
+ "upsell_offer",
1829
+ "upsell_video"
1830
+ ],
1831
+ "sdkRoots": [
1832
+ "data-next-upsell",
1833
+ "data-next-bundle-selector",
1834
+ "data-next-bundle-card",
1835
+ "data-next-timer"
1836
+ ],
1837
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note)."
1189
1838
  }
1190
1839
  ],
1191
1840
  "fixtures": [
@@ -1237,9 +1886,9 @@
1237
1886
  }
1238
1887
  },
1239
1888
  "verification": {
1240
- "sdk_version": "0.4.38",
1241
- "verified_at": "2026-09-15T16:51:10Z",
1242
- "evidence": "sdk-0.4.38-2026-09-15",
1889
+ "sdk_version": "0.4.40",
1890
+ "verified_at": "2026-10-01T04:56:01Z",
1891
+ "evidence": "sdk-0.4.40-2026-10-01",
1243
1892
  "status": "certified",
1244
1893
  "source": "template-verification.json"
1245
1894
  }
@@ -1252,7 +1901,8 @@
1252
1901
  "data-next-bundle-slots-for in checkout",
1253
1902
  "checkout-olympus-mv-full.js",
1254
1903
  "variant slot controls inside checkout",
1255
- "MV product gallery plus bundle slots on one page"
1904
+ "MV product gallery plus bundle slots on one page",
1905
+ "upsell-single page (single-offer add-on: one package, fixed price, accept or skip)"
1256
1906
  ],
1257
1907
  "canonicalSurfaces": {
1258
1908
  "mainSelector": "mv-configurable-selector",
@@ -1262,7 +1912,7 @@
1262
1912
  "payment": "payment-methods",
1263
1913
  "expressCheckout": "express-checkout|express-checkout-inline",
1264
1914
  "orderBump": "bump-check01|bump-check02|bump-check03|bump-switch01",
1265
- "upsell": "upsell-mv|upsell-bundle-stepper|upsell-bundle-tier-pills|upsell-bundle-tier-cards",
1915
+ "upsell": "upsell-mv|bundle-stepper|bundle-tier-pills|bundle-tier-cards|single (+ vsl page) — all via the shared upsell/offer.html shell (upsell_offer.type)",
1266
1916
  "receipt": "receipt-skeleton"
1267
1917
  },
1268
1918
  "frontmatterInputsNeeded": [
@@ -1282,7 +1932,22 @@
1282
1932
  "upsell_mv_tiers",
1283
1933
  "slot_personalization",
1284
1934
  "order_personalization",
1285
- "upsell_bundle_tiers"
1935
+ "upsell_bundle_tiers",
1936
+ "offer_features",
1937
+ "offer_comparison",
1938
+ "offer_steps",
1939
+ "guarantee_note",
1940
+ "countdown_timer",
1941
+ "announcement_text",
1942
+ "upsell_layout",
1943
+ "upsell_hero",
1944
+ "offer_bullets",
1945
+ "upsell_video",
1946
+ "upsell_guarantees",
1947
+ "upsell_body",
1948
+ "closing_cta",
1949
+ "ships_info",
1950
+ "payment_flags"
1286
1951
  ],
1287
1952
  "agentContract": {
1288
1953
  "status": "agent-ready",
@@ -1401,24 +2066,115 @@
1401
2066
  {
1402
2067
  "name": "MV upsell offers",
1403
2068
  "partials": [
1404
- "upsell-mv-offer.html",
1405
- "upsell-bundle-stepper-offer.html",
1406
- "upsell-bundle-tier-pills-offer.html",
1407
- "upsell-bundle-tier-cards-offer.html"
2069
+ "upsell/offer.html",
2070
+ "upsell/offer-context.html",
2071
+ "upsell/offer-tier.html",
2072
+ "upsell/offer-selector.html",
2073
+ "upsell/offer-controls.html",
2074
+ "upsell/offer-heading.html",
2075
+ "upsell/offer-bullets.html",
2076
+ "upsell/offer-prices.html",
2077
+ "upsell/offer-media.html",
2078
+ "upsell/cta.html",
2079
+ "upsell/decline.html",
2080
+ "upsell/ships-info.html",
2081
+ "upsell/video.html",
2082
+ "upsell/guarantees.html",
2083
+ "upsell/copy.html",
2084
+ "payment-logos.html (shared with checkout)",
2085
+ "upsell/announcement.html",
2086
+ "upsell/header-bar.html",
2087
+ "upsell/hero.html",
2088
+ "upsell/body.html",
2089
+ "upsell/reviews.html",
2090
+ "upsell/features.html",
2091
+ "upsell/comparison.html",
2092
+ "upsell/steps.html",
2093
+ "upsell/closing-cta.html"
1408
2094
  ],
1409
2095
  "ownedInputs": [
1410
- "upsell_offer",
1411
- "upsell_mv_tiers",
1412
- "slot_personalization",
2096
+ "announcement_text",
2097
+ "closing_cta",
2098
+ "countdown_timer",
2099
+ "offer_bullets",
1413
2100
  "order_personalization",
1414
- "upsell_bundle_tiers"
2101
+ "payment_flags",
2102
+ "ships_info",
2103
+ "slot_personalization",
2104
+ "upsell_body",
2105
+ "upsell_bundle_tiers",
2106
+ "upsell_guarantees",
2107
+ "upsell_hero",
2108
+ "upsell_layout",
2109
+ "upsell_mv_tiers",
2110
+ "upsell_offer",
2111
+ "upsell_video"
1415
2112
  ],
1416
2113
  "sdkRoots": [
1417
2114
  "data-next-upsell",
1418
2115
  "data-next-bundle-selector",
1419
2116
  "data-next-bundle-card",
1420
2117
  "data-next-bundle-slots-for"
1421
- ]
2118
+ ],
2119
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note). MV families: upsell-mv.html sets upsell_offer.type: mv; upsells-mv.js styles the SDK slot selects, upsells.js drives the qty pills and closing-CTA proxies."
2120
+ },
2121
+ {
2122
+ "name": "Olympus MV Single single-offer upsell page",
2123
+ "partials": [
2124
+ "upsell/offer.html",
2125
+ "upsell/offer-context.html",
2126
+ "upsell/offer-tier.html",
2127
+ "upsell/offer-selector.html",
2128
+ "upsell/offer-controls.html",
2129
+ "upsell/offer-heading.html",
2130
+ "upsell/offer-bullets.html",
2131
+ "upsell/offer-prices.html",
2132
+ "upsell/offer-media.html",
2133
+ "upsell/cta.html",
2134
+ "upsell/decline.html",
2135
+ "upsell/ships-info.html",
2136
+ "upsell/video.html",
2137
+ "upsell/guarantees.html",
2138
+ "upsell/copy.html",
2139
+ "payment-logos.html (shared with checkout)",
2140
+ "upsell/announcement.html",
2141
+ "upsell/header-bar.html",
2142
+ "upsell/hero.html",
2143
+ "upsell/body.html",
2144
+ "upsell/reviews.html",
2145
+ "upsell/features.html",
2146
+ "upsell/comparison.html",
2147
+ "upsell/steps.html",
2148
+ "upsell/closing-cta.html"
2149
+ ],
2150
+ "ownedInputs": [
2151
+ "announcement_text",
2152
+ "closing_cta",
2153
+ "countdown_timer",
2154
+ "guarantee_note",
2155
+ "offer_bullets",
2156
+ "offer_comparison",
2157
+ "offer_features",
2158
+ "offer_steps",
2159
+ "order_personalization",
2160
+ "payment_flags",
2161
+ "ships_info",
2162
+ "slot_personalization",
2163
+ "upsell_body",
2164
+ "upsell_guarantees",
2165
+ "upsell_hero",
2166
+ "upsell_layout",
2167
+ "upsell_mv_tiers",
2168
+ "upsell_offer",
2169
+ "upsell_video"
2170
+ ],
2171
+ "sdkRoots": [
2172
+ "data-next-upsell",
2173
+ "data-next-bundle-selector",
2174
+ "data-next-bundle-card",
2175
+ "data-next-timer"
2176
+ ],
2177
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note). MV families: upsell-mv.html sets upsell_offer.type: mv; upsells-mv.js styles the SDK slot selects, upsells.js drives the qty pills and closing-CTA proxies."
1422
2178
  }
1423
2179
  ],
1424
2180
  "fixtures": [
@@ -1471,9 +2227,9 @@
1471
2227
  }
1472
2228
  },
1473
2229
  "verification": {
1474
- "sdk_version": "0.4.38",
1475
- "verified_at": "2026-09-15T16:51:10Z",
1476
- "evidence": "sdk-0.4.38-2026-09-15",
2230
+ "sdk_version": "0.4.40",
2231
+ "verified_at": "2026-10-01T04:56:01Z",
2232
+ "evidence": "sdk-0.4.40-2026-10-01",
1477
2233
  "status": "certified",
1478
2234
  "source": "template-verification.json"
1479
2235
  }
@@ -1487,7 +2243,8 @@
1487
2243
  "data-next-bundle-slots-for in checkout",
1488
2244
  "mv-configurable-selector.html with Apollo layout partials",
1489
2245
  "selector_order_bump_variant and checkout_reveal frontmatter",
1490
- "checkout_step.selector_layout"
2246
+ "checkout_step.selector_layout",
2247
+ "upsell-single page (single-offer add-on: one package, fixed price, accept or skip)"
1491
2248
  ],
1492
2249
  "canonicalSurfaces": {
1493
2250
  "mainSelector": "mv-configurable-selector",
@@ -1500,7 +2257,7 @@
1500
2257
  "expressCheckout": "express-checkout|express-checkout-inline",
1501
2258
  "orderBump": "bump-check01|bump-check02|bump-check03|bump-switch01",
1502
2259
  "checkoutReveal": "checkout-form--reveal",
1503
- "upsell": "upsell-mv|upsell-bundle-stepper|upsell-bundle-tier-pills|upsell-bundle-tier-cards",
2260
+ "upsell": "upsell-mv|bundle-stepper|bundle-tier-pills|bundle-tier-cards|single (+ vsl page) — all via the shared upsell/offer.html shell (upsell_offer.type)",
1504
2261
  "receipt": "receipt-skeleton"
1505
2262
  },
1506
2263
  "frontmatterInputsNeeded": [
@@ -1518,7 +2275,7 @@
1518
2275
  "as_seen_in",
1519
2276
  "reviews",
1520
2277
  "guarantee",
1521
- "promo_timer",
2278
+ "countdown_timer",
1522
2279
  "promo_banner",
1523
2280
  "product_heading",
1524
2281
  "swiper_slides",
@@ -1529,7 +2286,21 @@
1529
2286
  "upsell_offer",
1530
2287
  "upsell_mv_tiers",
1531
2288
  "order_personalization",
1532
- "upsell_bundle_tiers"
2289
+ "upsell_bundle_tiers",
2290
+ "offer_features",
2291
+ "offer_comparison",
2292
+ "offer_steps",
2293
+ "guarantee_note",
2294
+ "announcement_text",
2295
+ "upsell_layout",
2296
+ "upsell_hero",
2297
+ "offer_bullets",
2298
+ "upsell_video",
2299
+ "upsell_guarantees",
2300
+ "upsell_body",
2301
+ "closing_cta",
2302
+ "ships_info",
2303
+ "payment_flags"
1533
2304
  ],
1534
2305
  "agentContract": {
1535
2306
  "status": "agent-ready",
@@ -1572,7 +2343,7 @@
1572
2343
  "reviews",
1573
2344
  "guarantee",
1574
2345
  "promo_banner",
1575
- "promo_timer",
2346
+ "countdown_timer",
1576
2347
  "product_heading",
1577
2348
  "swiper_slides",
1578
2349
  "swiper_thumbs",
@@ -1652,7 +2423,7 @@
1652
2423
  "checkout-header.html",
1653
2424
  "product-heading.html",
1654
2425
  "promo-banner.html",
1655
- "promo-timer.html",
2426
+ "countdown-timer.html",
1656
2427
  "as-seen-in.html",
1657
2428
  "reviews-slider.html",
1658
2429
  "guarantee.html"
@@ -1660,7 +2431,7 @@
1660
2431
  "ownedInputs": [
1661
2432
  "product_heading",
1662
2433
  "promo_banner",
1663
- "promo_timer",
2434
+ "countdown_timer",
1664
2435
  "as_seen_in",
1665
2436
  "reviews",
1666
2437
  "guarantee"
@@ -1729,24 +2500,115 @@
1729
2500
  {
1730
2501
  "name": "MV upsell offers",
1731
2502
  "partials": [
1732
- "upsell-mv-offer.html",
1733
- "upsell-bundle-stepper-offer.html",
1734
- "upsell-bundle-tier-pills-offer.html",
1735
- "upsell-bundle-tier-cards-offer.html"
2503
+ "upsell/offer.html",
2504
+ "upsell/offer-context.html",
2505
+ "upsell/offer-tier.html",
2506
+ "upsell/offer-selector.html",
2507
+ "upsell/offer-controls.html",
2508
+ "upsell/offer-heading.html",
2509
+ "upsell/offer-bullets.html",
2510
+ "upsell/offer-prices.html",
2511
+ "upsell/offer-media.html",
2512
+ "upsell/cta.html",
2513
+ "upsell/decline.html",
2514
+ "upsell/ships-info.html",
2515
+ "upsell/video.html",
2516
+ "upsell/guarantees.html",
2517
+ "upsell/copy.html",
2518
+ "payment-logos.html (shared with checkout)",
2519
+ "upsell/announcement.html",
2520
+ "upsell/header-bar.html",
2521
+ "upsell/hero.html",
2522
+ "upsell/body.html",
2523
+ "upsell/reviews.html",
2524
+ "upsell/features.html",
2525
+ "upsell/comparison.html",
2526
+ "upsell/steps.html",
2527
+ "upsell/closing-cta.html"
1736
2528
  ],
1737
2529
  "ownedInputs": [
1738
- "upsell_offer",
1739
- "upsell_mv_tiers",
1740
- "slot_personalization",
2530
+ "announcement_text",
2531
+ "closing_cta",
2532
+ "countdown_timer",
2533
+ "offer_bullets",
1741
2534
  "order_personalization",
1742
- "upsell_bundle_tiers"
2535
+ "payment_flags",
2536
+ "ships_info",
2537
+ "slot_personalization",
2538
+ "upsell_body",
2539
+ "upsell_bundle_tiers",
2540
+ "upsell_guarantees",
2541
+ "upsell_hero",
2542
+ "upsell_layout",
2543
+ "upsell_mv_tiers",
2544
+ "upsell_offer",
2545
+ "upsell_video"
1743
2546
  ],
1744
2547
  "sdkRoots": [
1745
2548
  "data-next-upsell",
1746
2549
  "data-next-bundle-selector",
1747
2550
  "data-next-bundle-card",
1748
2551
  "data-next-bundle-slots-for"
1749
- ]
2552
+ ],
2553
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note). MV families: upsell-mv.html sets upsell_offer.type: mv; upsells-mv.js styles the SDK slot selects, upsells.js drives the qty pills and closing-CTA proxies."
2554
+ },
2555
+ {
2556
+ "name": "Apollo MV Single single-offer upsell page",
2557
+ "partials": [
2558
+ "upsell/offer.html",
2559
+ "upsell/offer-context.html",
2560
+ "upsell/offer-tier.html",
2561
+ "upsell/offer-selector.html",
2562
+ "upsell/offer-controls.html",
2563
+ "upsell/offer-heading.html",
2564
+ "upsell/offer-bullets.html",
2565
+ "upsell/offer-prices.html",
2566
+ "upsell/offer-media.html",
2567
+ "upsell/cta.html",
2568
+ "upsell/decline.html",
2569
+ "upsell/ships-info.html",
2570
+ "upsell/video.html",
2571
+ "upsell/guarantees.html",
2572
+ "upsell/copy.html",
2573
+ "payment-logos.html (shared with checkout)",
2574
+ "upsell/announcement.html",
2575
+ "upsell/header-bar.html",
2576
+ "upsell/hero.html",
2577
+ "upsell/body.html",
2578
+ "upsell/reviews.html",
2579
+ "upsell/features.html",
2580
+ "upsell/comparison.html",
2581
+ "upsell/steps.html",
2582
+ "upsell/closing-cta.html"
2583
+ ],
2584
+ "ownedInputs": [
2585
+ "announcement_text",
2586
+ "closing_cta",
2587
+ "countdown_timer",
2588
+ "guarantee_note",
2589
+ "offer_bullets",
2590
+ "offer_comparison",
2591
+ "offer_features",
2592
+ "offer_steps",
2593
+ "order_personalization",
2594
+ "payment_flags",
2595
+ "ships_info",
2596
+ "slot_personalization",
2597
+ "upsell_body",
2598
+ "upsell_guarantees",
2599
+ "upsell_hero",
2600
+ "upsell_layout",
2601
+ "upsell_mv_tiers",
2602
+ "upsell_offer",
2603
+ "upsell_video"
2604
+ ],
2605
+ "sdkRoots": [
2606
+ "data-next-upsell",
2607
+ "data-next-bundle-selector",
2608
+ "data-next-bundle-card",
2609
+ "data-next-timer"
2610
+ ],
2611
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note). MV families: upsell-mv.html sets upsell_offer.type: mv; upsells-mv.js styles the SDK slot selects, upsells.js drives the qty pills and closing-CTA proxies."
1750
2612
  }
1751
2613
  ],
1752
2614
  "fixtures": [
@@ -1804,9 +2666,9 @@
1804
2666
  }
1805
2667
  },
1806
2668
  "verification": {
1807
- "sdk_version": "0.4.38",
1808
- "verified_at": "2026-09-15T16:51:10Z",
1809
- "evidence": "sdk-0.4.38-2026-09-15",
2669
+ "sdk_version": "0.4.40",
2670
+ "verified_at": "2026-10-01T04:56:01Z",
2671
+ "evidence": "sdk-0.4.40-2026-10-01",
1810
2672
  "status": "certified",
1811
2673
  "source": "template-verification.json"
1812
2674
  }
@@ -1819,7 +2681,8 @@
1819
2681
  "select.html before checkout.html",
1820
2682
  "checkout-olympus-mv-selection.js",
1821
2683
  "checkout-olympus-mv-full.js",
1822
- "variant selection step followed by payment step"
2684
+ "variant selection step followed by payment step",
2685
+ "upsell-single page (single-offer add-on: one package, fixed price, accept or skip)"
1823
2686
  ],
1824
2687
  "canonicalSurfaces": {
1825
2688
  "selectStep": "mv-selection-step",
@@ -1829,7 +2692,7 @@
1829
2692
  "orderSummary": "cart-summary03|cart-summary04",
1830
2693
  "payment": "payment-methods",
1831
2694
  "expressCheckout": "express-checkout|express-checkout-inline",
1832
- "upsell": "upsell-mv|upsell-bundle-stepper|upsell-bundle-tier-pills|upsell-bundle-tier-cards",
2695
+ "upsell": "upsell-mv|bundle-stepper|bundle-tier-pills|bundle-tier-cards|single (+ vsl page) — all via the shared upsell/offer.html shell (upsell_offer.type)",
1833
2696
  "receipt": "receipt-skeleton"
1834
2697
  },
1835
2698
  "frontmatterInputsNeeded": [
@@ -1849,7 +2712,22 @@
1849
2712
  "upsell_mv_tiers",
1850
2713
  "slot_personalization",
1851
2714
  "order_personalization",
1852
- "upsell_bundle_tiers"
2715
+ "upsell_bundle_tiers",
2716
+ "offer_features",
2717
+ "offer_comparison",
2718
+ "offer_steps",
2719
+ "guarantee_note",
2720
+ "countdown_timer",
2721
+ "announcement_text",
2722
+ "upsell_layout",
2723
+ "upsell_hero",
2724
+ "offer_bullets",
2725
+ "upsell_video",
2726
+ "upsell_guarantees",
2727
+ "upsell_body",
2728
+ "closing_cta",
2729
+ "ships_info",
2730
+ "payment_flags"
1853
2731
  ],
1854
2732
  "agentContract": {
1855
2733
  "status": "agent-ready",
@@ -1984,24 +2862,115 @@
1984
2862
  {
1985
2863
  "name": "MV upsell offers",
1986
2864
  "partials": [
1987
- "upsell-mv-offer.html",
1988
- "upsell-bundle-stepper-offer.html",
1989
- "upsell-bundle-tier-pills-offer.html",
1990
- "upsell-bundle-tier-cards-offer.html"
2865
+ "upsell/offer.html",
2866
+ "upsell/offer-context.html",
2867
+ "upsell/offer-tier.html",
2868
+ "upsell/offer-selector.html",
2869
+ "upsell/offer-controls.html",
2870
+ "upsell/offer-heading.html",
2871
+ "upsell/offer-bullets.html",
2872
+ "upsell/offer-prices.html",
2873
+ "upsell/offer-media.html",
2874
+ "upsell/cta.html",
2875
+ "upsell/decline.html",
2876
+ "upsell/ships-info.html",
2877
+ "upsell/video.html",
2878
+ "upsell/guarantees.html",
2879
+ "upsell/copy.html",
2880
+ "payment-logos.html (shared with checkout)",
2881
+ "upsell/announcement.html",
2882
+ "upsell/header-bar.html",
2883
+ "upsell/hero.html",
2884
+ "upsell/body.html",
2885
+ "upsell/reviews.html",
2886
+ "upsell/features.html",
2887
+ "upsell/comparison.html",
2888
+ "upsell/steps.html",
2889
+ "upsell/closing-cta.html"
1991
2890
  ],
1992
2891
  "ownedInputs": [
1993
- "upsell_offer",
1994
- "upsell_mv_tiers",
1995
- "slot_personalization",
2892
+ "announcement_text",
2893
+ "closing_cta",
2894
+ "countdown_timer",
2895
+ "offer_bullets",
1996
2896
  "order_personalization",
1997
- "upsell_bundle_tiers"
2897
+ "payment_flags",
2898
+ "ships_info",
2899
+ "slot_personalization",
2900
+ "upsell_body",
2901
+ "upsell_bundle_tiers",
2902
+ "upsell_guarantees",
2903
+ "upsell_hero",
2904
+ "upsell_layout",
2905
+ "upsell_mv_tiers",
2906
+ "upsell_offer",
2907
+ "upsell_video"
1998
2908
  ],
1999
2909
  "sdkRoots": [
2000
2910
  "data-next-upsell",
2001
2911
  "data-next-bundle-selector",
2002
2912
  "data-next-bundle-card",
2003
2913
  "data-next-bundle-slots-for"
2004
- ]
2914
+ ],
2915
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note). MV families: upsell-mv.html sets upsell_offer.type: mv; upsells-mv.js styles the SDK slot selects, upsells.js drives the qty pills and closing-CTA proxies."
2916
+ },
2917
+ {
2918
+ "name": "Olympus MV Two Step single-offer upsell page",
2919
+ "partials": [
2920
+ "upsell/offer.html",
2921
+ "upsell/offer-context.html",
2922
+ "upsell/offer-tier.html",
2923
+ "upsell/offer-selector.html",
2924
+ "upsell/offer-controls.html",
2925
+ "upsell/offer-heading.html",
2926
+ "upsell/offer-bullets.html",
2927
+ "upsell/offer-prices.html",
2928
+ "upsell/offer-media.html",
2929
+ "upsell/cta.html",
2930
+ "upsell/decline.html",
2931
+ "upsell/ships-info.html",
2932
+ "upsell/video.html",
2933
+ "upsell/guarantees.html",
2934
+ "upsell/copy.html",
2935
+ "payment-logos.html (shared with checkout)",
2936
+ "upsell/announcement.html",
2937
+ "upsell/header-bar.html",
2938
+ "upsell/hero.html",
2939
+ "upsell/body.html",
2940
+ "upsell/reviews.html",
2941
+ "upsell/features.html",
2942
+ "upsell/comparison.html",
2943
+ "upsell/steps.html",
2944
+ "upsell/closing-cta.html"
2945
+ ],
2946
+ "ownedInputs": [
2947
+ "announcement_text",
2948
+ "closing_cta",
2949
+ "countdown_timer",
2950
+ "guarantee_note",
2951
+ "offer_bullets",
2952
+ "offer_comparison",
2953
+ "offer_features",
2954
+ "offer_steps",
2955
+ "order_personalization",
2956
+ "payment_flags",
2957
+ "ships_info",
2958
+ "slot_personalization",
2959
+ "upsell_body",
2960
+ "upsell_guarantees",
2961
+ "upsell_hero",
2962
+ "upsell_layout",
2963
+ "upsell_mv_tiers",
2964
+ "upsell_offer",
2965
+ "upsell_video"
2966
+ ],
2967
+ "sdkRoots": [
2968
+ "data-next-upsell",
2969
+ "data-next-bundle-selector",
2970
+ "data-next-bundle-card",
2971
+ "data-next-timer"
2972
+ ],
2973
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note). MV families: upsell-mv.html sets upsell_offer.type: mv; upsells-mv.js styles the SDK slot selects, upsells.js drives the qty pills and closing-CTA proxies."
2005
2974
  }
2006
2975
  ],
2007
2976
  "fixtures": [
@@ -2054,9 +3023,9 @@
2054
3023
  }
2055
3024
  },
2056
3025
  "verification": {
2057
- "sdk_version": "0.4.38",
2058
- "verified_at": "2026-09-15T16:51:10Z",
2059
- "evidence": "sdk-0.4.38-2026-09-15",
3026
+ "sdk_version": "0.4.40",
3027
+ "verified_at": "2026-10-01T04:56:01Z",
3028
+ "evidence": "sdk-0.4.40-2026-10-01",
2060
3029
  "status": "certified",
2061
3030
  "source": "template-verification.json"
2062
3031
  }
@@ -2068,14 +3037,15 @@
2068
3037
  "shop-three-step in spec, path, or export metadata",
2069
3038
  "information.html -> shipping.html -> billing.html flow",
2070
3039
  "checkout-shop-three-shipping.js dynamic shipping options",
2071
- "separate shipping method page before billing"
3040
+ "separate shipping method page before billing",
3041
+ "upsell-single page (single-offer add-on: one package, fixed price, accept or skip)"
2072
3042
  ],
2073
3043
  "canonicalSurfaces": {
2074
3044
  "informationStep": "shipping/contact form",
2075
3045
  "shippingStep": "dynamic shipping methods from SDK getShippingMethods()",
2076
3046
  "billingStep": "payment-methods and checkout review",
2077
3047
  "receipt": "receipt-skeleton",
2078
- "upsell": "bundle-stepper|bundle-tier-pills|bundle-tier-cards"
3048
+ "upsell": "bundle-stepper|bundle-tier-pills|bundle-tier-cards|single (+ vsl page) — all via the shared upsell/offer.html shell (upsell_offer.type)"
2079
3049
  },
2080
3050
  "frontmatterInputsNeeded": [
2081
3051
  "receipt_summary"
@@ -2088,7 +3058,22 @@
2088
3058
  "swiper_slides",
2089
3059
  "swiper_thumbs",
2090
3060
  "upsell_offer",
2091
- "upsell_bundle_tiers"
3061
+ "upsell_bundle_tiers",
3062
+ "offer_features",
3063
+ "offer_comparison",
3064
+ "offer_steps",
3065
+ "guarantee_note",
3066
+ "countdown_timer",
3067
+ "announcement_text",
3068
+ "upsell_layout",
3069
+ "upsell_hero",
3070
+ "offer_bullets",
3071
+ "upsell_video",
3072
+ "upsell_guarantees",
3073
+ "upsell_body",
3074
+ "closing_cta",
3075
+ "ships_info",
3076
+ "payment_flags"
2092
3077
  ],
2093
3078
  "agentContract": {
2094
3079
  "status": "upsell-include-driven",
@@ -2181,19 +3166,109 @@
2181
3166
  {
2182
3167
  "name": "upsell selectors/actions",
2183
3168
  "partials": [
2184
- "upsell-bundle-stepper-offer.html",
2185
- "upsell-bundle-tier-pills-offer.html",
2186
- "upsell-bundle-tier-cards-offer.html"
3169
+ "upsell/offer.html",
3170
+ "upsell/offer-context.html",
3171
+ "upsell/offer-tier.html",
3172
+ "upsell/offer-selector.html",
3173
+ "upsell/offer-controls.html",
3174
+ "upsell/offer-heading.html",
3175
+ "upsell/offer-bullets.html",
3176
+ "upsell/offer-prices.html",
3177
+ "upsell/offer-media.html",
3178
+ "upsell/cta.html",
3179
+ "upsell/decline.html",
3180
+ "upsell/ships-info.html",
3181
+ "upsell/video.html",
3182
+ "upsell/guarantees.html",
3183
+ "upsell/copy.html",
3184
+ "payment-logos.html (shared with checkout)",
3185
+ "upsell/announcement.html",
3186
+ "upsell/header-bar.html",
3187
+ "upsell/hero.html",
3188
+ "upsell/body.html",
3189
+ "upsell/reviews.html",
3190
+ "upsell/features.html",
3191
+ "upsell/comparison.html",
3192
+ "upsell/steps.html",
3193
+ "upsell/closing-cta.html"
2187
3194
  ],
2188
3195
  "ownedInputs": [
3196
+ "announcement_text",
3197
+ "closing_cta",
3198
+ "countdown_timer",
3199
+ "offer_bullets",
3200
+ "payment_flags",
3201
+ "ships_info",
3202
+ "upsell_body",
3203
+ "upsell_bundle_tiers",
3204
+ "upsell_guarantees",
3205
+ "upsell_hero",
3206
+ "upsell_layout",
2189
3207
  "upsell_offer",
2190
- "upsell_bundle_tiers"
3208
+ "upsell_video"
2191
3209
  ],
2192
3210
  "sdkRoots": [
2193
3211
  "data-next-upsell",
2194
3212
  "data-next-bundle-selector",
2195
3213
  "data-next-bundle-card"
2196
- ]
3214
+ ],
3215
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note)."
3216
+ },
3217
+ {
3218
+ "name": "Shop Three Step single-offer upsell page",
3219
+ "partials": [
3220
+ "upsell/offer.html",
3221
+ "upsell/offer-context.html",
3222
+ "upsell/offer-tier.html",
3223
+ "upsell/offer-selector.html",
3224
+ "upsell/offer-controls.html",
3225
+ "upsell/offer-heading.html",
3226
+ "upsell/offer-bullets.html",
3227
+ "upsell/offer-prices.html",
3228
+ "upsell/offer-media.html",
3229
+ "upsell/cta.html",
3230
+ "upsell/decline.html",
3231
+ "upsell/ships-info.html",
3232
+ "upsell/video.html",
3233
+ "upsell/guarantees.html",
3234
+ "upsell/copy.html",
3235
+ "payment-logos.html (shared with checkout)",
3236
+ "upsell/announcement.html",
3237
+ "upsell/header-bar.html",
3238
+ "upsell/hero.html",
3239
+ "upsell/body.html",
3240
+ "upsell/reviews.html",
3241
+ "upsell/features.html",
3242
+ "upsell/comparison.html",
3243
+ "upsell/steps.html",
3244
+ "upsell/closing-cta.html"
3245
+ ],
3246
+ "ownedInputs": [
3247
+ "announcement_text",
3248
+ "closing_cta",
3249
+ "countdown_timer",
3250
+ "guarantee_note",
3251
+ "offer_bullets",
3252
+ "offer_comparison",
3253
+ "offer_features",
3254
+ "offer_steps",
3255
+ "payment_flags",
3256
+ "ships_info",
3257
+ "upsell_body",
3258
+ "upsell_bundle_tiers",
3259
+ "upsell_guarantees",
3260
+ "upsell_hero",
3261
+ "upsell_layout",
3262
+ "upsell_offer",
3263
+ "upsell_video"
3264
+ ],
3265
+ "sdkRoots": [
3266
+ "data-next-upsell",
3267
+ "data-next-bundle-selector",
3268
+ "data-next-bundle-card",
3269
+ "data-next-timer"
3270
+ ],
3271
+ "note": "Same composable upsell set as apollo (generated from _shared/upsell/; see the apollo 'Apollo bundle upsell pages' surface note)."
2197
3272
  }
2198
3273
  ],
2199
3274
  "fixtures": [
@@ -2238,9 +3313,9 @@
2238
3313
  }
2239
3314
  },
2240
3315
  "verification": {
2241
- "sdk_version": "0.4.38",
2242
- "verified_at": "2026-09-15T16:51:10Z",
2243
- "evidence": "sdk-0.4.38-2026-09-15",
3316
+ "sdk_version": "0.4.40",
3317
+ "verified_at": "2026-10-01T04:56:01Z",
3318
+ "evidence": "sdk-0.4.40-2026-10-01",
2244
3319
  "status": "certified",
2245
3320
  "source": "template-verification.json"
2246
3321
  }
@@ -2450,5 +3525,5 @@
2450
3525
  },
2451
3526
  "_synced_from_repo": "NextCommerceCo/campaign-cart-starter-templates",
2452
3527
  "_synced_from_ref": "main",
2453
- "_synced_from_sha": "11352c30c596db258679fd3a552b906086b11bb9"
3528
+ "_synced_from_sha": "3793b1de3b77cc31dffe9176f47e8e99ea6134aa"
2454
3529
  }