@odla-ai/chapter 0.40.3 → 0.41.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.
@@ -105,7 +105,7 @@ function SlotPicker(props) {
105
105
  }
106
106
 
107
107
  // src/ui/members.tsx
108
- import { useEffect as useEffect3, useState as useState6 } from "preact/hooks";
108
+ import { useEffect as useEffect3, useState as useState7 } from "preact/hooks";
109
109
 
110
110
  // src/ui/reschedule.tsx
111
111
  import { useState as useState2 } from "preact/hooks";
@@ -190,7 +190,7 @@ function Rescheduler(props) {
190
190
  }
191
191
 
192
192
  // src/ui/member-gifts.tsx
193
- import { useEffect, useRef as useRef2, useState as useState4 } from "preact/hooks";
193
+ import { useEffect, useRef as useRef2, useState as useState5 } from "preact/hooks";
194
194
 
195
195
  // src/ui/gift-offer-cards.tsx
196
196
  import { jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
@@ -208,9 +208,78 @@ function GiftOfferCards(props) {
208
208
  ] }, offer.id)) });
209
209
  }
210
210
 
211
+ // src/ui/gift-code-redeemer.tsx
212
+ import { InlineActionField } from "@odla-ai/ui/components";
213
+ import { useState as useState3 } from "preact/hooks";
214
+ import { jsx as jsx4 } from "preact/jsx-runtime";
215
+ function GiftCodeRedeemer({ api, copy, id, onRedeemed }) {
216
+ const [code, setCode] = useState3("");
217
+ const [loading, setLoading] = useState3(false);
218
+ const [message, setMessage] = useState3("");
219
+ const [messageTone, setMessageTone] = useState3("neutral");
220
+ const normalizedCode = code.trim();
221
+ const redeem = async () => {
222
+ if (!normalizedCode || loading) return;
223
+ setLoading(true);
224
+ setMessage("");
225
+ setMessageTone("neutral");
226
+ try {
227
+ await api("/api/gifts/redeem", {
228
+ method: "POST",
229
+ headers: { "content-type": "application/json" },
230
+ body: JSON.stringify({ code: normalizedCode })
231
+ });
232
+ setCode("");
233
+ setMessage(copy.redeemed);
234
+ setMessageTone("success");
235
+ try {
236
+ await onRedeemed?.();
237
+ } catch {
238
+ }
239
+ } catch {
240
+ setMessage(copy.redeemFailed);
241
+ setMessageTone("error");
242
+ } finally {
243
+ setLoading(false);
244
+ }
245
+ };
246
+ return /* @__PURE__ */ jsx4(
247
+ InlineActionField,
248
+ {
249
+ id,
250
+ className: "gift-code-redeemer",
251
+ label: copy.code,
252
+ value: code,
253
+ code: true,
254
+ actionLabel: copy.redeem,
255
+ loadingLabel: `${copy.redeem}\u2026`,
256
+ loading,
257
+ actionDisabled: !normalizedCode,
258
+ message,
259
+ messageTone,
260
+ inputProps: {
261
+ name: "giftCode",
262
+ maxLength: 64,
263
+ autoComplete: "one-time-code",
264
+ autoCapitalize: "none",
265
+ autocorrect: "off",
266
+ spellcheck: false
267
+ },
268
+ onValueChange: (value) => {
269
+ setCode(value);
270
+ if (message) {
271
+ setMessage("");
272
+ setMessageTone("neutral");
273
+ }
274
+ },
275
+ onAction: () => void redeem()
276
+ }
277
+ );
278
+ }
279
+
211
280
  // src/ui/payment-step.tsx
212
- import { useRef, useState as useState3 } from "preact/hooks";
213
- import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
281
+ import { useRef, useState as useState4 } from "preact/hooks";
282
+ import { jsx as jsx5, jsxs as jsxs4 } from "preact/jsx-runtime";
214
283
  var loader = null;
215
284
  function loadStripe() {
216
285
  const existing = globalThis.Stripe;
@@ -244,9 +313,9 @@ function PaymentStep(props) {
244
313
  simulation
245
314
  } = props;
246
315
  const copy = props.copy ?? inheritedCopy.join.payment;
247
- const [status, setStatus] = useState3("idle");
248
- const [error, setError] = useState3(null);
249
- const [lineItems, setLineItems] = useState3(null);
316
+ const [status, setStatus] = useState4("idle");
317
+ const [error, setError] = useState4(null);
318
+ const [lineItems, setLineItems] = useState4(null);
250
319
  const mountRef = useRef(null);
251
320
  const stripeRef = useRef(null);
252
321
  const elementsRef = useRef(null);
@@ -322,10 +391,10 @@ function PaymentStep(props) {
322
391
  };
323
392
  return /* @__PURE__ */ jsxs4("div", { className: "join-pay", children: [
324
393
  /* @__PURE__ */ jsxs4("div", { className: "compliance-box", children: [
325
- merchantDisclosureText ? /* @__PURE__ */ jsx4("p", { className: "compliance-merchant", children: merchantDisclosureText }) : null,
326
- /* @__PURE__ */ jsx4("p", { className: "compliance-policy", children: refundPolicyText }),
394
+ merchantDisclosureText ? /* @__PURE__ */ jsx5("p", { className: "compliance-merchant", children: merchantDisclosureText }) : null,
395
+ /* @__PURE__ */ jsx5("p", { className: "compliance-policy", children: refundPolicyText }),
327
396
  /* @__PURE__ */ jsxs4("label", { className: "compliance-check", children: [
328
- /* @__PURE__ */ jsx4(
397
+ /* @__PURE__ */ jsx5(
329
398
  "input",
330
399
  {
331
400
  type: "checkbox",
@@ -335,42 +404,41 @@ function PaymentStep(props) {
335
404
  }
336
405
  }
337
406
  ),
338
- copy.consent ? /* @__PURE__ */ jsx4("span", { children: copy.consent }) : null
407
+ copy.consent ? /* @__PURE__ */ jsx5("span", { children: copy.consent }) : null
339
408
  ] })
340
409
  ] }),
341
- status === "loading" ? /* @__PURE__ */ jsx4("p", { className: "pay-status", children: copy.preparing }) : null,
410
+ status === "loading" ? /* @__PURE__ */ jsx5("p", { className: "pay-status", children: copy.preparing }) : null,
342
411
  lineItems && renderPriceLines ? renderPriceLines(lineItems) : null,
343
412
  children,
344
413
  simulation && (status === "ready" || status === "confirming") ? /* @__PURE__ */ jsxs4("fieldset", { className: "join-pay-simulation", children: [
345
- /* @__PURE__ */ jsx4("legend", { children: "Payment details" }),
414
+ /* @__PURE__ */ jsx5("legend", { children: "Payment details" }),
346
415
  /* @__PURE__ */ jsxs4("label", { children: [
347
416
  "Card number",
348
- /* @__PURE__ */ jsx4("input", { name: "simulationCardNumber", inputMode: "numeric", autoComplete: "off", defaultValue: "4242 4242 4242 4242" })
417
+ /* @__PURE__ */ jsx5("input", { name: "simulationCardNumber", inputMode: "numeric", autoComplete: "off", defaultValue: "4242 4242 4242 4242" })
349
418
  ] }),
350
419
  /* @__PURE__ */ jsxs4("label", { children: [
351
420
  "Expiration",
352
- /* @__PURE__ */ jsx4("input", { name: "simulationCardExpiry", inputMode: "numeric", autoComplete: "off", defaultValue: "12 / 34" })
421
+ /* @__PURE__ */ jsx5("input", { name: "simulationCardExpiry", inputMode: "numeric", autoComplete: "off", defaultValue: "12 / 34" })
353
422
  ] }),
354
423
  /* @__PURE__ */ jsxs4("label", { children: [
355
424
  "Security code",
356
- /* @__PURE__ */ jsx4("input", { name: "simulationCardCvc", inputMode: "numeric", autoComplete: "off", defaultValue: "123" })
425
+ /* @__PURE__ */ jsx5("input", { name: "simulationCardCvc", inputMode: "numeric", autoComplete: "off", defaultValue: "123" })
357
426
  ] }),
358
- /* @__PURE__ */ jsx4("p", { children: "This is a simulation. No card data is sent and no charge is created." })
427
+ /* @__PURE__ */ jsx5("p", { children: "This is a simulation. No card data is sent and no charge is created." })
359
428
  ] }) : null,
360
- /* @__PURE__ */ jsx4("div", { ref: mountRef, hidden: status === "idle" || status === "loading" }),
361
- status === "ready" || status === "confirming" ? /* @__PURE__ */ jsx4("button", { className: "submit-btn", disabled: status === "confirming", onClick: () => void pay(), children: status === "confirming" ? copy.processing : copy.payAndContinue }) : null,
362
- error ? /* @__PURE__ */ jsx4("p", { className: "pay-error", children: error }) : null
429
+ /* @__PURE__ */ jsx5("div", { ref: mountRef, hidden: status === "idle" || status === "loading" }),
430
+ status === "ready" || status === "confirming" ? /* @__PURE__ */ jsx5("button", { className: "submit-btn", disabled: status === "confirming", onClick: () => void pay(), children: status === "confirming" ? copy.processing : copy.payAndContinue }) : null,
431
+ error ? /* @__PURE__ */ jsx5("p", { className: "pay-error", children: error }) : null
363
432
  ] });
364
433
  }
365
434
 
366
435
  // src/ui/member-gifts.tsx
367
- import { jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
436
+ import { jsx as jsx6, jsxs as jsxs5 } from "preact/jsx-runtime";
368
437
  function MemberGifts(props) {
369
- const [data, setData] = useState4(null);
370
- const [selected, setSelected] = useState4(null);
371
- const [code, setCode] = useState4("");
372
- const [redeemCode, setRedeemCode] = useState4("");
373
- const [message, setMessage] = useState4("");
438
+ const [data, setData] = useState5(null);
439
+ const [selected, setSelected] = useState5(null);
440
+ const [code, setCode] = useState5("");
441
+ const [message, setMessage] = useState5("");
374
442
  const purchaseId = useRef2(crypto.randomUUID());
375
443
  const load = async () => setData(await props.api("/api/gifts"));
376
444
  useEffect(() => {
@@ -385,32 +453,18 @@ function MemberGifts(props) {
385
453
  setMessage(props.copy.rotateFailed);
386
454
  }
387
455
  };
388
- const redeem = async () => {
389
- try {
390
- await props.api("/api/gifts/redeem", {
391
- method: "POST",
392
- headers: { "content-type": "application/json" },
393
- body: JSON.stringify({ code: redeemCode })
394
- });
395
- setRedeemCode("");
396
- setMessage(props.copy.redeemed);
397
- await load();
398
- } catch {
399
- setMessage(props.copy.redeemFailed);
400
- }
401
- };
402
456
  if (!data) return null;
403
457
  const offer = data.offers.find((item) => item.id === selected);
404
458
  return /* @__PURE__ */ jsxs5("section", { className: "member-gifts", children: [
405
459
  /* @__PURE__ */ jsxs5("div", { className: "card", children: [
406
- /* @__PURE__ */ jsx5("div", { className: "card-label", children: props.copy.title }),
407
- /* @__PURE__ */ jsx5("p", { children: props.copy.body }),
408
- data.offers.length ? /* @__PURE__ */ jsx5(GiftOfferCards, { offers: data.offers, mode: "select", selectedOfferId: selected, onSelect: (id) => {
460
+ /* @__PURE__ */ jsx6("div", { className: "card-label", children: props.copy.title }),
461
+ /* @__PURE__ */ jsx6("p", { children: props.copy.body }),
462
+ data.offers.length ? /* @__PURE__ */ jsx6(GiftOfferCards, { offers: data.offers, mode: "select", selectedOfferId: selected, onSelect: (id) => {
409
463
  setSelected(id);
410
464
  setCode("");
411
465
  purchaseId.current = crypto.randomUUID();
412
- } }) : /* @__PURE__ */ jsx5("p", { children: props.copy.noneAvailable }),
413
- offer ? /* @__PURE__ */ jsx5(
466
+ } }) : /* @__PURE__ */ jsx6("p", { children: props.copy.noneAvailable }),
467
+ offer ? /* @__PURE__ */ jsx6(
414
468
  PaymentStep,
415
469
  {
416
470
  applicationId: purchaseId.current,
@@ -431,34 +485,30 @@ function MemberGifts(props) {
431
485
  }
432
486
  ) : null,
433
487
  code ? /* @__PURE__ */ jsxs5("div", { className: "gift-code-once", children: [
434
- /* @__PURE__ */ jsx5("output", { children: code }),
435
- /* @__PURE__ */ jsx5("p", { children: props.copy.saveCode })
488
+ /* @__PURE__ */ jsx6("output", { children: code }),
489
+ /* @__PURE__ */ jsx6("p", { children: props.copy.saveCode })
436
490
  ] }) : null
437
491
  ] }),
438
492
  /* @__PURE__ */ jsxs5("div", { className: "card", children: [
439
- /* @__PURE__ */ jsx5("div", { className: "card-label", children: props.copy.purchases }),
493
+ /* @__PURE__ */ jsx6("div", { className: "card-label", children: props.copy.purchases }),
440
494
  data.claims.length ? data.claims.map((claim) => /* @__PURE__ */ jsxs5("div", { className: "member-row", children: [
441
- /* @__PURE__ */ jsx5("span", { children: claim.offerId }),
442
- /* @__PURE__ */ jsx5("span", { children: props.copy[claim.status] }),
443
- claim.status === "pending" ? /* @__PURE__ */ jsx5("button", { className: "btn secondary mini", onClick: () => void rotate(claim.id), children: props.copy.rotate }) : null
444
- ] }, claim.id)) : /* @__PURE__ */ jsx5("p", { children: props.copy.noPurchases })
495
+ /* @__PURE__ */ jsx6("span", { children: claim.offerId }),
496
+ /* @__PURE__ */ jsx6("span", { children: props.copy[claim.status] }),
497
+ claim.status === "pending" ? /* @__PURE__ */ jsx6("button", { className: "btn secondary mini", onClick: () => void rotate(claim.id), children: props.copy.rotate }) : null
498
+ ] }, claim.id)) : /* @__PURE__ */ jsx6("p", { children: props.copy.noPurchases })
445
499
  ] }),
446
500
  /* @__PURE__ */ jsxs5("div", { className: "card", children: [
447
- /* @__PURE__ */ jsx5("div", { className: "card-label", children: props.copy.redeemTitle }),
448
- /* @__PURE__ */ jsxs5("label", { children: [
449
- props.copy.code,
450
- /* @__PURE__ */ jsx5("input", { value: redeemCode, maxLength: 64, onInput: (event) => setRedeemCode(event.currentTarget.value) })
451
- ] }),
452
- /* @__PURE__ */ jsx5("button", { className: "btn secondary", disabled: !redeemCode, onClick: () => void redeem(), children: props.copy.redeem }),
453
- message ? /* @__PURE__ */ jsx5("p", { role: "status", children: message }) : null
501
+ /* @__PURE__ */ jsx6("div", { className: "card-label", children: props.copy.redeemTitle }),
502
+ /* @__PURE__ */ jsx6(GiftCodeRedeemer, { api: props.api, copy: props.copy, onRedeemed: load }),
503
+ message ? /* @__PURE__ */ jsx6("p", { role: "status", children: message }) : null
454
504
  ] })
455
505
  ] });
456
506
  }
457
507
 
458
508
  // src/ui/member-content.tsx
459
- import { useEffect as useEffect2, useMemo as useMemo2, useState as useState5 } from "preact/hooks";
509
+ import { useEffect as useEffect2, useMemo as useMemo2, useState as useState6 } from "preact/hooks";
460
510
  import { Markdown } from "@odla-ai/ui/components";
461
- import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "preact/jsx-runtime";
511
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs6 } from "preact/jsx-runtime";
462
512
  var pageLabel = (page) => `${page.title}${page.access === "locked" ? " \xB7 Locked" : ""}`;
463
513
  function MemberContentArea(props) {
464
514
  const {
@@ -466,12 +516,12 @@ function MemberContentArea(props) {
466
516
  path = "/api/member-content",
467
517
  upsellHref,
468
518
  onUpsell,
469
- loadingContent = /* @__PURE__ */ jsx6("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
470
- emptyContent = /* @__PURE__ */ jsx6("p", { className: "meeting-note", children: "No member pages have been published yet." })
519
+ loadingContent = /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
520
+ emptyContent = /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: "No member pages have been published yet." })
471
521
  } = props;
472
- const [data, setData] = useState5(props.initialData ?? null);
473
- const [error, setError] = useState5(null);
474
- const [selectedId, setSelectedId] = useState5(
522
+ const [data, setData] = useState6(props.initialData ?? null);
523
+ const [error, setError] = useState6(null);
524
+ const [selectedId, setSelectedId] = useState6(
475
525
  props.initialPageId ?? props.initialData?.pages[0]?.id ?? ""
476
526
  );
477
527
  useEffect2(() => {
@@ -500,14 +550,14 @@ function MemberContentArea(props) {
500
550
  "Member pages could not be loaded: ",
501
551
  error
502
552
  ] });
503
- if (!data) return /* @__PURE__ */ jsx6(Fragment2, { children: loadingContent });
504
- if (data.pages.length === 0) return /* @__PURE__ */ jsx6(Fragment2, { children: emptyContent });
553
+ if (!data) return /* @__PURE__ */ jsx7(Fragment2, { children: loadingContent });
554
+ if (data.pages.length === 0) return /* @__PURE__ */ jsx7(Fragment2, { children: emptyContent });
505
555
  const selected = data.pages.find((page) => page.id === selectedId) ?? data.pages[0];
506
556
  const href = selected.upsell && upsellHref ? upsellHref(selected.upsell.tierId, selected) : void 0;
507
557
  return /* @__PURE__ */ jsxs6("div", { className: "chapter-member-content", "data-member-content": true, children: [
508
- /* @__PURE__ */ jsx6("nav", { className: "chapter-member-content-nav", "aria-label": "Member pages", children: sections.map(([section, pages]) => /* @__PURE__ */ jsxs6("section", { className: "chapter-member-content-section", children: [
509
- /* @__PURE__ */ jsx6("h2", { children: section }),
510
- /* @__PURE__ */ jsx6("ul", { children: pages.map((page) => /* @__PURE__ */ jsx6("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx6(
558
+ /* @__PURE__ */ jsx7("nav", { className: "chapter-member-content-nav", "aria-label": "Member pages", children: sections.map(([section, pages]) => /* @__PURE__ */ jsxs6("section", { className: "chapter-member-content-section", children: [
559
+ /* @__PURE__ */ jsx7("h2", { children: section }),
560
+ /* @__PURE__ */ jsx7("ul", { children: pages.map((page) => /* @__PURE__ */ jsx7("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx7(
511
561
  "button",
512
562
  {
513
563
  type: "button",
@@ -524,16 +574,16 @@ function MemberContentArea(props) {
524
574
  " \xB7 ",
525
575
  selected.access
526
576
  ] }),
527
- /* @__PURE__ */ jsx6("h1", { children: selected.title }),
528
- selected.summary ? /* @__PURE__ */ jsx6("p", { children: selected.summary }) : null
577
+ /* @__PURE__ */ jsx7("h1", { children: selected.title }),
578
+ selected.summary ? /* @__PURE__ */ jsx7("p", { children: selected.summary }) : null
529
579
  ] }),
530
- selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx6(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs6("div", { className: "chapter-member-content-locked", children: [
531
- selected.teaserMarkdown ? /* @__PURE__ */ jsx6(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx6("p", { children: "This page is not included in your current membership." }),
580
+ selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx7(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs6("div", { className: "chapter-member-content-locked", children: [
581
+ selected.teaserMarkdown ? /* @__PURE__ */ jsx7(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx7("p", { children: "This page is not included in your current membership." }),
532
582
  selected.upsell ? /* @__PURE__ */ jsxs6("aside", { className: "chapter-member-content-upsell", "aria-label": selected.upsell.label ?? "Membership option", children: [
533
- /* @__PURE__ */ jsx6("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
534
- /* @__PURE__ */ jsx6("p", { children: fmtMoney(selected.upsell.priceCents) }),
535
- selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx6(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
536
- href ? /* @__PURE__ */ jsx6("a", { className: "btn primary", href, children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : onUpsell ? /* @__PURE__ */ jsx6("button", { className: "btn primary", type: "button", onClick: () => onUpsell(selected.upsell.tierId, selected), children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : null
583
+ /* @__PURE__ */ jsx7("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
584
+ /* @__PURE__ */ jsx7("p", { children: fmtMoney(selected.upsell.priceCents) }),
585
+ selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx7(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
586
+ href ? /* @__PURE__ */ jsx7("a", { className: "btn primary", href, children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : onUpsell ? /* @__PURE__ */ jsx7("button", { className: "btn primary", type: "button", onClick: () => onUpsell(selected.upsell.tierId, selected), children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : null
537
587
  ] }) : null
538
588
  ] })
539
589
  ] })
@@ -541,12 +591,12 @@ function MemberContentArea(props) {
541
591
  }
542
592
 
543
593
  // src/ui/members.tsx
544
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "preact/jsx-runtime";
594
+ import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs7 } from "preact/jsx-runtime";
545
595
  function card(copy, kicker, body) {
546
596
  return /* @__PURE__ */ jsxs7("div", { className: "card", children: [
547
- /* @__PURE__ */ jsx7("div", { className: "card-label", children: copy.provisional.cardLabel }),
597
+ /* @__PURE__ */ jsx8("div", { className: "card-label", children: copy.provisional.cardLabel }),
548
598
  /* @__PURE__ */ jsxs7("div", { className: "meeting-block", children: [
549
- /* @__PURE__ */ jsx7("div", { className: "meeting-kicker", children: kicker }),
599
+ /* @__PURE__ */ jsx8("div", { className: "meeting-kicker", children: kicker }),
550
600
  body
551
601
  ] })
552
602
  ] });
@@ -558,8 +608,8 @@ function ProvisionalCard(props) {
558
608
  copy,
559
609
  copy.provisional.applicationNeeded,
560
610
  /* @__PURE__ */ jsxs7(Fragment3, { children: [
561
- /* @__PURE__ */ jsx7("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
562
- /* @__PURE__ */ jsx7("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
611
+ /* @__PURE__ */ jsx8("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
612
+ /* @__PURE__ */ jsx8("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
563
613
  ] })
564
614
  );
565
615
  }
@@ -567,19 +617,19 @@ function ProvisionalCard(props) {
567
617
  return card(
568
618
  copy,
569
619
  copy.provisional.refunded,
570
- /* @__PURE__ */ jsx7("div", { className: "meeting-note", children: copy.provisional.refundedBody })
620
+ /* @__PURE__ */ jsx8("div", { className: "meeting-note", children: copy.provisional.refundedBody })
571
621
  );
572
622
  }
573
- const membership = application.paid ? /* @__PURE__ */ jsx7("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
623
+ const membership = application.paid ? /* @__PURE__ */ jsx8("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
574
624
  if (application.meetingAt) {
575
625
  return card(
576
626
  copy,
577
627
  copy.provisional.introductionCall,
578
628
  /* @__PURE__ */ jsxs7(Fragment3, { children: [
579
- /* @__PURE__ */ jsx7("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
580
- /* @__PURE__ */ jsx7("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
581
- application.meetUrl ? /* @__PURE__ */ jsx7("div", { className: "meeting-note", children: /* @__PURE__ */ jsx7("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
582
- /* @__PURE__ */ jsx7(
629
+ /* @__PURE__ */ jsx8("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
630
+ /* @__PURE__ */ jsx8("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
631
+ application.meetUrl ? /* @__PURE__ */ jsx8("div", { className: "meeting-note", children: /* @__PURE__ */ jsx8("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
632
+ /* @__PURE__ */ jsx8(
583
633
  Rescheduler,
584
634
  {
585
635
  api,
@@ -597,8 +647,8 @@ function ProvisionalCard(props) {
597
647
  copy,
598
648
  copy.provisional.bookCall,
599
649
  /* @__PURE__ */ jsxs7(Fragment3, { children: [
600
- /* @__PURE__ */ jsx7("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
601
- /* @__PURE__ */ jsx7(
650
+ /* @__PURE__ */ jsx8("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
651
+ /* @__PURE__ */ jsx8(
602
652
  Rescheduler,
603
653
  {
604
654
  api,
@@ -625,8 +675,8 @@ function MembersArea(props) {
625
675
  renderProvisional
626
676
  } = props;
627
677
  const copy = props.copy ?? inheritedCopy.members;
628
- const [me, setMe] = useState6(null);
629
- const [error, setError] = useState6(false);
678
+ const [me, setMe] = useState7(null);
679
+ const [error, setError] = useState7(false);
630
680
  const reload = async () => {
631
681
  try {
632
682
  setMe(await api("/api/me"));
@@ -637,22 +687,22 @@ function MembersArea(props) {
637
687
  useEffect3(() => {
638
688
  void reload();
639
689
  }, []);
640
- if (error) return /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: copy.loadFailed });
641
- if (!me) return /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: inheritedCopy.common.loading });
690
+ if (error) return /* @__PURE__ */ jsx8("p", { className: "meeting-note", children: copy.loadFailed });
691
+ if (!me) return /* @__PURE__ */ jsx8("p", { className: "meeting-note", children: inheritedCopy.common.loading });
642
692
  const role = me.role || "provisional";
643
693
  return /* @__PURE__ */ jsxs7(Fragment3, { children: [
644
694
  /* @__PURE__ */ jsxs7("div", { className: "card", children: [
645
695
  /* @__PURE__ */ jsxs7("div", { className: "member-row", children: [
646
- /* @__PURE__ */ jsx7("span", { className: "member-email", children: me.email }),
647
- /* @__PURE__ */ jsx7("span", { className: "role-badge " + role, children: role })
696
+ /* @__PURE__ */ jsx8("span", { className: "member-email", children: me.email }),
697
+ /* @__PURE__ */ jsx8("span", { className: "role-badge " + role, children: role })
648
698
  ] }),
649
699
  /* @__PURE__ */ jsxs7("div", { className: "account-actions", children: [
650
- /* @__PURE__ */ jsx7("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
651
- role === "admin" ? /* @__PURE__ */ jsx7("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
700
+ /* @__PURE__ */ jsx8("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
701
+ role === "admin" ? /* @__PURE__ */ jsx8("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
652
702
  ] })
653
703
  ] }),
654
704
  role === "provisional" ? (() => {
655
- const defaultContent = /* @__PURE__ */ jsx7(
705
+ const defaultContent = /* @__PURE__ */ jsx8(
656
706
  ProvisionalCard,
657
707
  {
658
708
  api,
@@ -669,29 +719,29 @@ function MembersArea(props) {
669
719
  reload,
670
720
  defaultContent
671
721
  }) ?? defaultContent;
672
- })() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx7(
722
+ })() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx8(
673
723
  MemberContentArea,
674
724
  {
675
725
  api,
676
726
  ...memberPages === true ? {} : memberPages
677
727
  }
678
- ) : /* @__PURE__ */ jsx7("div", { className: "card", children: /* @__PURE__ */ jsx7("div", { className: "card-label", children: copy.full.welcome }) })),
679
- /* @__PURE__ */ jsx7(MemberGifts, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment })
728
+ ) : /* @__PURE__ */ jsx8("div", { className: "card", children: /* @__PURE__ */ jsx8("div", { className: "card-label", children: copy.full.welcome }) })),
729
+ /* @__PURE__ */ jsx8(MemberGifts, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment })
680
730
  ] });
681
731
  }
682
732
 
683
733
  // src/ui/join.tsx
684
- import { useEffect as useEffect5, useRef as useRef3, useState as useState10 } from "preact/hooks";
734
+ import { useEffect as useEffect5, useRef as useRef3, useState as useState11 } from "preact/hooks";
685
735
 
686
736
  // src/ui/join-booking.tsx
687
- import { useEffect as useEffect4, useState as useState7 } from "preact/hooks";
688
- import { jsx as jsx8, jsxs as jsxs8 } from "preact/jsx-runtime";
737
+ import { useEffect as useEffect4, useState as useState8 } from "preact/hooks";
738
+ import { jsx as jsx9, jsxs as jsxs8 } from "preact/jsx-runtime";
689
739
  function JoinBooking(props) {
690
740
  const { applicationId, copy, onBooked, simulation } = props;
691
- const [state, setState] = useState7(null);
692
- const [msg, setMsg] = useState7(null);
693
- const [busy, setBusy] = useState7(false);
694
- const [selected, setSelected] = useState7(null);
741
+ const [state, setState] = useState8(null);
742
+ const [msg, setMsg] = useState8(null);
743
+ const [busy, setBusy] = useState8(false);
744
+ const [selected, setSelected] = useState8(null);
695
745
  const load = async () => {
696
746
  setMsg(null);
697
747
  try {
@@ -748,9 +798,9 @@ function JoinBooking(props) {
748
798
  setBusy(false);
749
799
  }
750
800
  };
751
- if (!state) return /* @__PURE__ */ jsx8("p", { className: "slots-status", children: msg ?? copy.loading });
801
+ if (!state) return /* @__PURE__ */ jsx9("p", { className: "slots-status", children: msg ?? copy.loading });
752
802
  return /* @__PURE__ */ jsxs8("div", { className: "join-book", children: [
753
- /* @__PURE__ */ jsx8(
803
+ /* @__PURE__ */ jsx9(
754
804
  SlotPicker,
755
805
  {
756
806
  slots: state.slots,
@@ -761,28 +811,28 @@ function JoinBooking(props) {
761
811
  }
762
812
  ),
763
813
  /* @__PURE__ */ jsxs8("div", { className: "slot-confirm", hidden: !selected, children: [
764
- /* @__PURE__ */ jsx8("button", { className: "submit-btn", disabled: busy, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
765
- msg ? /* @__PURE__ */ jsx8("p", { className: "step2-note", children: msg }) : null
814
+ /* @__PURE__ */ jsx9("button", { className: "submit-btn", disabled: busy, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
815
+ msg ? /* @__PURE__ */ jsx9("p", { className: "step2-note", children: msg }) : null
766
816
  ] })
767
817
  ] });
768
818
  }
769
819
 
770
820
  // src/ui/join-accepted.tsx
771
- import { jsx as jsx9, jsxs as jsxs9 } from "preact/jsx-runtime";
821
+ import { jsx as jsx10, jsxs as jsxs9 } from "preact/jsx-runtime";
772
822
  function JoinAccepted(props) {
773
823
  return /* @__PURE__ */ jsxs9("div", { className: "join-done card", children: [
774
- /* @__PURE__ */ jsx9("div", { className: "card-label", children: props.copy.accepted.label }),
775
- /* @__PURE__ */ jsx9("p", { className: "meeting-note", children: props.copy.accepted.body }),
776
- /* @__PURE__ */ jsx9("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
824
+ /* @__PURE__ */ jsx10("div", { className: "card-label", children: props.copy.accepted.label }),
825
+ /* @__PURE__ */ jsx10("p", { className: "meeting-note", children: props.copy.accepted.body }),
826
+ /* @__PURE__ */ jsx10("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
777
827
  ] });
778
828
  }
779
829
 
780
830
  // src/ui/gift-claim-card.tsx
781
- import { useState as useState8 } from "preact/hooks";
782
- import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs10 } from "preact/jsx-runtime";
831
+ import { useState as useState9 } from "preact/hooks";
832
+ import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs10 } from "preact/jsx-runtime";
783
833
  function GiftClaimCard(props) {
784
- const [code, setCode] = useState8(props.initialCode ?? "");
785
- const [error, setError] = useState8(false);
834
+ const [code, setCode] = useState9(props.initialCode ?? "");
835
+ const [error, setError] = useState9(false);
786
836
  const rotate = async () => {
787
837
  if (!props.claimId) return;
788
838
  setError(false);
@@ -796,22 +846,22 @@ function GiftClaimCard(props) {
796
846
  else setError(true);
797
847
  };
798
848
  return /* @__PURE__ */ jsxs10("div", { className: "join-done card", children: [
799
- /* @__PURE__ */ jsx10("div", { className: "card-label", children: props.copy.label }),
800
- /* @__PURE__ */ jsx10("p", { className: "meeting-note", children: props.copy.body }),
849
+ /* @__PURE__ */ jsx11("div", { className: "card-label", children: props.copy.label }),
850
+ /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: props.copy.body }),
801
851
  code ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
802
- /* @__PURE__ */ jsx10("output", { className: "gift-code", children: code }),
803
- /* @__PURE__ */ jsx10("p", { children: props.copy.save })
852
+ /* @__PURE__ */ jsx11("output", { className: "gift-code", children: code }),
853
+ /* @__PURE__ */ jsx11("p", { children: props.copy.save })
804
854
  ] }) : null,
805
- !code && props.claimId ? /* @__PURE__ */ jsx10("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
806
- error ? /* @__PURE__ */ jsx10("p", { role: "alert", children: props.copy.rotateFailed }) : null
855
+ !code && props.claimId ? /* @__PURE__ */ jsx11("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
856
+ error ? /* @__PURE__ */ jsx11("p", { role: "alert", children: props.copy.rotateFailed }) : null
807
857
  ] });
808
858
  }
809
859
 
810
860
  // src/ui/join-tiers.tsx
811
- import { useState as useState9 } from "preact/hooks";
812
- import { jsx as jsx11, jsxs as jsxs11 } from "preact/jsx-runtime";
861
+ import { useState as useState10 } from "preact/hooks";
862
+ import { jsx as jsx12, jsxs as jsxs11 } from "preact/jsx-runtime";
813
863
  function useTierSelection(tiers, initialTierId) {
814
- const [selectedTierId, setSelectedTierId] = useState9(() => {
864
+ const [selectedTierId, setSelectedTierId] = useState10(() => {
815
865
  const preset = tiers.find((tier) => tier.id === initialTierId);
816
866
  if (preset) return preset.id;
817
867
  return tiers.length === 1 ? tiers[0].id : null;
@@ -827,9 +877,9 @@ function useTierSelection(tiers, initialTierId) {
827
877
  }
828
878
  function TierPlaceholder(context) {
829
879
  return /* @__PURE__ */ jsxs11("fieldset", { "data-chapter-placeholder": "tiers", children: [
830
- /* @__PURE__ */ jsx11("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
880
+ /* @__PURE__ */ jsx12("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
831
881
  context.tiers.map((tier) => /* @__PURE__ */ jsxs11("label", { children: [
832
- /* @__PURE__ */ jsx11(
882
+ /* @__PURE__ */ jsx12(
833
883
  "input",
834
884
  {
835
885
  type: "radio",
@@ -861,7 +911,7 @@ async function loadJoinResume(applicationId, fetcher = fetch) {
861
911
  }
862
912
 
863
913
  // src/ui/join.tsx
864
- import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs12 } from "preact/jsx-runtime";
914
+ import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs12 } from "preact/jsx-runtime";
865
915
  function JoinIsland(props) {
866
916
  const inheritedCopy = useChapterCopy();
867
917
  const {
@@ -878,10 +928,10 @@ function JoinIsland(props) {
878
928
  const tiers = config.tiers ?? [];
879
929
  const tierSelection = useTierSelection(tiers, props.initialTierId);
880
930
  const { selectedTierId, selected: selectedTier } = tierSelection;
881
- const [state, setState] = useState10(props.initialState ?? { step: "form" });
882
- const [error, setError] = useState10(null);
883
- const [submitting, setSubmitting] = useState10(false);
884
- const [giftOfferId, setGiftOfferId] = useState10(props.initialGiftOfferId ?? null);
931
+ const [state, setState] = useState11(props.initialState ?? { step: "form" });
932
+ const [error, setError] = useState11(null);
933
+ const [submitting, setSubmitting] = useState11(false);
934
+ const [giftOfferId, setGiftOfferId] = useState11(props.initialGiftOfferId ?? null);
885
935
  const simulatedPayment = props.simulation ? props.simulation.payment ?? {
886
936
  lineItems: {
887
937
  standardCents: selectedTier?.priceCents ?? 0,
@@ -982,10 +1032,10 @@ function JoinIsland(props) {
982
1032
  });
983
1033
  if (state.step === "done") {
984
1034
  const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs12("div", { className: "join-done card", children: [
985
- /* @__PURE__ */ jsx12("div", { className: "card-label", children: copy.done.label }),
986
- /* @__PURE__ */ jsx12("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
987
- /* @__PURE__ */ jsx12("p", { className: "meeting-note", children: copy.done.calendarInvite }),
988
- /* @__PURE__ */ jsx12("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
1035
+ /* @__PURE__ */ jsx13("div", { className: "card-label", children: copy.done.label }),
1036
+ /* @__PURE__ */ jsx13("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
1037
+ /* @__PURE__ */ jsx13("p", { className: "meeting-note", children: copy.done.calendarInvite }),
1038
+ /* @__PURE__ */ jsx13("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
989
1039
  ] });
990
1040
  return /* @__PURE__ */ jsxs12(Fragment5, { children: [
991
1041
  header,
@@ -993,14 +1043,14 @@ function JoinIsland(props) {
993
1043
  ] });
994
1044
  }
995
1045
  if (state.step === "accepted") {
996
- const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx12(JoinAccepted, { copy, membersHref });
1046
+ const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx13(JoinAccepted, { copy, membersHref });
997
1047
  return /* @__PURE__ */ jsxs12(Fragment5, { children: [
998
1048
  header,
999
1049
  body
1000
1050
  ] });
1001
1051
  }
1002
1052
  if (state.step === "gift") {
1003
- const body = renderGift?.(state) ?? /* @__PURE__ */ jsx12(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
1053
+ const body = renderGift?.(state) ?? /* @__PURE__ */ jsx13(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
1004
1054
  return /* @__PURE__ */ jsxs12(Fragment5, { children: [
1005
1055
  header,
1006
1056
  body
@@ -1009,7 +1059,7 @@ function JoinIsland(props) {
1009
1059
  if (state.step === "booking") {
1010
1060
  return /* @__PURE__ */ jsxs12(Fragment5, { children: [
1011
1061
  header,
1012
- /* @__PURE__ */ jsx12(
1062
+ /* @__PURE__ */ jsx13(
1013
1063
  JoinBooking,
1014
1064
  {
1015
1065
  applicationId: state.applicationId,
@@ -1025,7 +1075,7 @@ function JoinIsland(props) {
1025
1075
  if (state.step === "payment") {
1026
1076
  return /* @__PURE__ */ jsxs12(Fragment5, { children: [
1027
1077
  header,
1028
- /* @__PURE__ */ jsx12(
1078
+ /* @__PURE__ */ jsx13(
1029
1079
  PaymentStep,
1030
1080
  {
1031
1081
  applicationId: state.applicationId,
@@ -1055,7 +1105,7 @@ function JoinIsland(props) {
1055
1105
  if (state.step === "paymentPending") {
1056
1106
  return /* @__PURE__ */ jsxs12(Fragment5, { children: [
1057
1107
  header,
1058
- /* @__PURE__ */ jsx12("p", { className: "pay-status", role: "status", children: copy.payment.pending })
1108
+ /* @__PURE__ */ jsx13("p", { className: "pay-status", role: "status", children: copy.payment.pending })
1059
1109
  ] });
1060
1110
  }
1061
1111
  const submitDisabled = submitting || props.submitDisabled === true;
@@ -1064,14 +1114,14 @@ function JoinIsland(props) {
1064
1114
  header,
1065
1115
  /* @__PURE__ */ jsxs12("form", { className: "join-form", onSubmit: (e) => void submit(e), children: [
1066
1116
  (config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs12("fieldset", { children: [
1067
- /* @__PURE__ */ jsx12("legend", { children: copy.gift.optionsLabel }),
1068
- /* @__PURE__ */ jsx12("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => setGiftOfferId(null), children: copy.gift.chooseSelf }),
1069
- /* @__PURE__ */ jsx12(GiftOfferCards, { offers: config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: setGiftOfferId })
1117
+ /* @__PURE__ */ jsx13("legend", { children: copy.gift.optionsLabel }),
1118
+ /* @__PURE__ */ jsx13("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => setGiftOfferId(null), children: copy.gift.chooseSelf }),
1119
+ /* @__PURE__ */ jsx13(GiftOfferCards, { offers: config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: setGiftOfferId })
1070
1120
  ] }) : null,
1071
1121
  tierChooser,
1072
1122
  children,
1073
- error ? /* @__PURE__ */ jsx12("p", { className: "join-error", children: error }) : null,
1074
- renderSubmit?.({ submitting, disabled: submitDisabled }) ?? /* @__PURE__ */ jsx12("button", { className: "submit-btn", type: "submit", disabled: submitDisabled, children: submitting ? copy.form.submitting : copy.form.submit })
1123
+ error ? /* @__PURE__ */ jsx13("p", { className: "join-error", children: error }) : null,
1124
+ renderSubmit?.({ submitting, disabled: submitDisabled }) ?? /* @__PURE__ */ jsx13("button", { className: "submit-btn", type: "submit", disabled: submitDisabled, children: submitting ? copy.form.submitting : copy.form.submit })
1075
1125
  ] })
1076
1126
  ] });
1077
1127
  }
@@ -1248,7 +1298,7 @@ function membershipPageDocument(input, options = {}) {
1248
1298
  }
1249
1299
 
1250
1300
  // src/ui/membership-cards.tsx
1251
- import { jsx as jsx13, jsxs as jsxs13 } from "preact/jsx-runtime";
1301
+ import { jsx as jsx14, jsxs as jsxs13 } from "preact/jsx-runtime";
1252
1302
  var MEMBERSHIP_CARD_TOKEN_DEFAULTS = Object.freeze({
1253
1303
  "--ui-membership-grid-gap": "1.4rem",
1254
1304
  "--ui-membership-card-padding": "2rem 1.7rem 1.8rem",
@@ -1319,18 +1369,18 @@ function TierAction(props) {
1319
1369
  if (props.mode === "select") {
1320
1370
  return /* @__PURE__ */ jsxs13("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
1321
1371
  props.label,
1322
- /* @__PURE__ */ jsx13("span", { "aria-hidden": "true", children: "\u2192" })
1372
+ /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: "\u2192" })
1323
1373
  ] });
1324
1374
  }
1325
1375
  if (props.mode === "preview") {
1326
1376
  return /* @__PURE__ */ jsxs13("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
1327
1377
  props.label,
1328
- /* @__PURE__ */ jsx13("span", { "aria-hidden": "true", children: "\u2192" })
1378
+ /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: "\u2192" })
1329
1379
  ] });
1330
1380
  }
1331
1381
  return /* @__PURE__ */ jsxs13("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
1332
1382
  props.label,
1333
- /* @__PURE__ */ jsx13("span", { "aria-hidden": "true", children: "\u2192" })
1383
+ /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: "\u2192" })
1334
1384
  ] });
1335
1385
  }
1336
1386
  function TierCard(props) {
@@ -1338,33 +1388,33 @@ function TierCard(props) {
1338
1388
  const summary = presentation.summaryMarkdown ?? tier.blurb;
1339
1389
  const action = presentation.ctaLabel ?? (tier.free ? "Join for free" : `Choose ${tier.name}`);
1340
1390
  return /* @__PURE__ */ jsxs13("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
1341
- presentation.badge ? /* @__PURE__ */ jsx13("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
1342
- /* @__PURE__ */ jsx13("h3", { className: "chapter-membership-name", children: tier.name }),
1391
+ presentation.badge ? /* @__PURE__ */ jsx14("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
1392
+ /* @__PURE__ */ jsx14("h3", { className: "chapter-membership-name", children: tier.name }),
1343
1393
  /* @__PURE__ */ jsxs13("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
1344
1394
  presentation.capacity ? /* @__PURE__ */ jsxs13("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
1345
- /* @__PURE__ */ jsx13("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
1346
- /* @__PURE__ */ jsx13("small", { children: presentation.capacity.label ?? "available" })
1395
+ /* @__PURE__ */ jsx14("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
1396
+ /* @__PURE__ */ jsx14("small", { children: presentation.capacity.label ?? "available" })
1347
1397
  ] }) : null,
1348
1398
  /* @__PURE__ */ jsxs13("div", { className: "chapter-membership-price-stack", children: [
1349
- presentation.priceEyebrow ? /* @__PURE__ */ jsx13("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : null,
1399
+ presentation.priceEyebrow ? /* @__PURE__ */ jsx14("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : null,
1350
1400
  /* @__PURE__ */ jsxs13("div", { className: "chapter-membership-price-row", children: [
1351
- presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx13("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
1352
- /* @__PURE__ */ jsx13("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.priceCents) }),
1353
- !tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx13("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
1401
+ presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx14("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
1402
+ /* @__PURE__ */ jsx14("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.priceCents) }),
1403
+ !tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx14("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
1354
1404
  ] })
1355
1405
  ] })
1356
1406
  ] }),
1357
- presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx13(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
1358
- summary ? /* @__PURE__ */ jsx13(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
1359
- presentation.benefits?.length ? /* @__PURE__ */ jsx13("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs13("li", { children: [
1360
- /* @__PURE__ */ jsx13("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
1361
- /* @__PURE__ */ jsx13(Markdown2, { className: "chapter-membership-benefit", source: benefit })
1407
+ presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx14(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
1408
+ summary ? /* @__PURE__ */ jsx14(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
1409
+ presentation.benefits?.length ? /* @__PURE__ */ jsx14("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs13("li", { children: [
1410
+ /* @__PURE__ */ jsx14("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
1411
+ /* @__PURE__ */ jsx14(Markdown2, { className: "chapter-membership-benefit", source: benefit })
1362
1412
  ] }, `${tier.id}-benefit-${index}`)) }) : null,
1363
1413
  presentation.callout ? /* @__PURE__ */ jsxs13("aside", { className: "chapter-membership-callout", children: [
1364
- presentation.callout.label ? /* @__PURE__ */ jsx13("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
1365
- /* @__PURE__ */ jsx13(Markdown2, { source: presentation.callout.bodyMarkdown })
1414
+ presentation.callout.label ? /* @__PURE__ */ jsx14("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
1415
+ /* @__PURE__ */ jsx14(Markdown2, { source: presentation.callout.bodyMarkdown })
1366
1416
  ] }) : null,
1367
- /* @__PURE__ */ jsx13(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
1417
+ /* @__PURE__ */ jsx14(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
1368
1418
  ] });
1369
1419
  }
1370
1420
  function MembershipCards(props) {
@@ -1372,12 +1422,12 @@ function MembershipCards(props) {
1372
1422
  const byId = new Map(props.tiers.map((tier) => [tier.id, tier]));
1373
1423
  const mode = props.mode ?? "link";
1374
1424
  return /* @__PURE__ */ jsxs13("section", { className: ["chapter-membership", props.className].filter(Boolean).join(" "), "data-chapter-membership": MEMBERSHIP_PAGE_RENDERER, "aria-label": props.ariaLabel ?? "Membership options", children: [
1375
- /* @__PURE__ */ jsx13("style", { children: MEMBERSHIP_CARDS_CSS }),
1376
- /* @__PURE__ */ jsx13("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
1425
+ /* @__PURE__ */ jsx14("style", { children: MEMBERSHIP_CARDS_CSS }),
1426
+ /* @__PURE__ */ jsx14("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
1377
1427
  const tier = byId.get(presentation.tierId);
1378
- return /* @__PURE__ */ jsx13(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
1428
+ return /* @__PURE__ */ jsx14(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
1379
1429
  }) }),
1380
- document2.footnoteMarkdown ? /* @__PURE__ */ jsx13(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
1430
+ document2.footnoteMarkdown ? /* @__PURE__ */ jsx14(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
1381
1431
  ] });
1382
1432
  }
1383
1433
 
@@ -1393,6 +1443,7 @@ export {
1393
1443
  SlotPicker,
1394
1444
  Rescheduler,
1395
1445
  GiftOfferCards,
1446
+ GiftCodeRedeemer,
1396
1447
  PaymentStep,
1397
1448
  MemberGifts,
1398
1449
  MemberContentArea,
@@ -1406,4 +1457,4 @@ export {
1406
1457
  membershipApplicationHref,
1407
1458
  MembershipCards
1408
1459
  };
1409
- //# sourceMappingURL=chunk-E5OXQ3DC.js.map
1460
+ //# sourceMappingURL=chunk-JLLRZO7B.js.map