@odla-ai/chapter 0.54.2 → 0.55.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.
@@ -111,10 +111,10 @@ function SlotPicker(props) {
111
111
  }
112
112
 
113
113
  // src/ui/member-restart.tsx
114
- import { useEffect as useEffect2, useState as useState4 } from "preact/hooks";
114
+ import { useEffect as useEffect2, useState as useState5 } from "preact/hooks";
115
115
 
116
116
  // src/ui/membership-payment-step.tsx
117
- import { useEffect, useState as useState3 } from "preact/hooks";
117
+ import { useEffect, useState as useState4 } from "preact/hooks";
118
118
 
119
119
  // src/ui/payment-step.tsx
120
120
  import { useRef, useState as useState2 } from "preact/hooks";
@@ -271,14 +271,95 @@ function PaymentStep(props) {
271
271
  ] });
272
272
  }
273
273
 
274
- // src/ui/membership-payment-step.tsx
274
+ // src/ui/checkout-seat-choice.tsx
275
+ import { useState as useState3 } from "preact/hooks";
275
276
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
277
+ function CheckoutSeatChoice(props) {
278
+ const saved = props.quote.namedSeat;
279
+ const [selected, setSelected] = useState3(Boolean(saved || props.initial));
280
+ const [name, setName] = useState3(saved?.recipientName ?? props.initial?.recipientName ?? "");
281
+ const [email, setEmail] = useState3(saved?.recipientEmail ?? props.initial?.recipientEmail ?? "");
282
+ const [saving, setSaving] = useState3(false), [error, setError] = useState3("");
283
+ const amount = props.quote.seatOffer.amountCents;
284
+ const money = new Intl.NumberFormat("en-US", { style: "currency", currency: props.quote.currency }).format(amount / 100);
285
+ const dirty = selected !== Boolean(saved) || selected && (name !== saved?.recipientName || email !== saved?.recipientEmail);
286
+ const edit = (nextSelected, nextName = name, nextEmail = email) => {
287
+ props.onEditing(nextSelected !== Boolean(saved) || nextSelected && (nextName !== saved?.recipientName || nextEmail !== saved?.recipientEmail));
288
+ setError("");
289
+ };
290
+ return /* @__PURE__ */ jsx3("section", { className: "checkout-seat-choice", "aria-label": "Additional member", children: /* @__PURE__ */ jsxs3("form", { onSubmit: async (event) => {
291
+ event.preventDefault();
292
+ setSaving(true);
293
+ setError("");
294
+ try {
295
+ await props.onChange(selected ? { recipientName: name, recipientEmail: email } : null);
296
+ } catch (error2) {
297
+ setError(error2 instanceof Error ? error2.message : "Could not update your total. Try again.");
298
+ } finally {
299
+ setSaving(false);
300
+ }
301
+ }, children: [
302
+ /* @__PURE__ */ jsxs3("fieldset", { disabled: props.locked || saving, children: [
303
+ /* @__PURE__ */ jsx3("legend", { children: amount === 0 ? "Included additional member" : "Add an additional member" }),
304
+ /* @__PURE__ */ jsx3("p", { children: amount === 0 ? "Your membership includes one additional member at no extra charge." : `Additional-member rate: ${money} per ${props.quote.interval}, paid together with your membership.` }),
305
+ /* @__PURE__ */ jsxs3("label", { children: [
306
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", checked: selected, onChange: (event) => {
307
+ setSelected(event.currentTarget.checked);
308
+ edit(event.currentTarget.checked);
309
+ } }),
310
+ amount === 0 ? "Include my additional member" : "Add one member to my payment"
311
+ ] }),
312
+ selected ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
313
+ /* @__PURE__ */ jsxs3("label", { children: [
314
+ "Recipient name",
315
+ /* @__PURE__ */ jsx3(
316
+ "input",
317
+ {
318
+ required: true,
319
+ minLength: 2,
320
+ maxLength: 160,
321
+ value: name,
322
+ onInput: (event) => {
323
+ setName(event.currentTarget.value);
324
+ edit(selected, event.currentTarget.value);
325
+ }
326
+ }
327
+ )
328
+ ] }),
329
+ /* @__PURE__ */ jsxs3("label", { children: [
330
+ "Recipient email",
331
+ /* @__PURE__ */ jsx3(
332
+ "input",
333
+ {
334
+ required: true,
335
+ type: "email",
336
+ maxLength: 254,
337
+ value: email,
338
+ onInput: (event) => {
339
+ setEmail(event.currentTarget.value);
340
+ edit(selected, name, event.currentTarget.value);
341
+ }
342
+ }
343
+ )
344
+ ] }),
345
+ /* @__PURE__ */ jsx3("p", { children: "This seat belongs to one named person and cannot be reassigned. They must accept and complete their own application and any required interview. It renews and ends with your membership. Contact the chapter if you need a refund." })
346
+ ] }) : /* @__PURE__ */ jsx3("p", { children: "You can add someone from your member page after paying." }),
347
+ dirty ? /* @__PURE__ */ jsx3("button", { type: "submit", disabled: saving, children: saving ? "Updating total\u2026" : "Update total" }) : null
348
+ ] }),
349
+ error ? /* @__PURE__ */ jsx3("p", { role: "alert", children: error }) : null
350
+ ] }) });
351
+ }
352
+
353
+ // src/ui/membership-payment-step.tsx
354
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
276
355
  function MembershipPaymentStep(props) {
277
356
  const inherited = useChapterCopy();
278
357
  const copy = props.copy ?? inherited.join.payment;
279
- const [quote, setQuote] = useState3(null);
280
- const [error, setError] = useState3(false);
281
- const [revision, setRevision] = useState3(0);
358
+ const [quote, setQuote] = useState4(null);
359
+ const [locked, setLocked] = useState4(false), [editing, setEditing] = useState4(Boolean(props.initialNamedSeat));
360
+ const [seatTerms, setSeatTerms] = useState4(false), [prefillConsumed, setPrefillConsumed] = useState4(false);
361
+ const [error, setError] = useState4(false);
362
+ const [revision, setRevision] = useState4(0);
282
363
  useEffect(() => {
283
364
  let live = true;
284
365
  setQuote(null);
@@ -286,8 +367,14 @@ function MembershipPaymentStep(props) {
286
367
  void fetch(`/api/payments/quote?application=${encodeURIComponent(props.applicationId)}`, { method: "POST", cache: "no-store" }).then(async (response) => {
287
368
  if (!response.ok) throw new Error("quote unavailable");
288
369
  const value = await response.json();
370
+ value.checkoutStarted = response.headers.get("x-chapter-checkout-started") === "true";
289
371
  if (value.applicationId !== props.applicationId || !/^[a-f0-9]{64}$/.test(value.digest) || !/^[a-z]{3}$/.test(value.currency) || !Number.isSafeInteger(value.lineItems?.dueTodayCents) || value.lineItems.dueTodayCents <= 0 || typeof value.refundPolicyText !== "string") throw new Error("invalid quote");
290
- if (live) setQuote(value);
372
+ if (live) {
373
+ setQuote(value);
374
+ setLocked(Boolean(value.checkoutStarted));
375
+ setSeatTerms(Boolean(value.checkoutStarted));
376
+ setEditing(Boolean(props.initialNamedSeat && !prefillConsumed && !value.namedSeat && !value.checkoutStarted && value.seatOffer));
377
+ }
291
378
  }).catch(() => {
292
379
  if (live) setError(true);
293
380
  });
@@ -299,16 +386,22 @@ function MembershipPaymentStep(props) {
299
386
  setQuote(null);
300
387
  setRevision((value) => value + 1);
301
388
  };
302
- if (!quote || quote.applicationId !== props.applicationId) return /* @__PURE__ */ jsxs3("div", { className: "join-pay", role: "status", children: [
303
- props.merchantDisclosureText ? /* @__PURE__ */ jsx3("p", { className: "compliance-merchant", children: props.merchantDisclosureText }) : null,
304
- /* @__PURE__ */ jsx3("p", { children: error ? copy.setupFailed : copy.preparing }),
305
- error ? /* @__PURE__ */ jsx3("button", { type: "button", onClick: refresh, children: "Reload payment terms" }) : null
389
+ if (!quote || quote.applicationId !== props.applicationId) return /* @__PURE__ */ jsxs4("div", { className: "join-pay", role: "status", children: [
390
+ props.merchantDisclosureText ? /* @__PURE__ */ jsx4("p", { className: "compliance-merchant", children: props.merchantDisclosureText }) : null,
391
+ /* @__PURE__ */ jsx4("p", { children: error ? copy.setupFailed : copy.preparing }),
392
+ error ? /* @__PURE__ */ jsx4("button", { type: "button", onClick: refresh, children: "Reload payment terms" }) : null
306
393
  ] });
307
394
  const startCheckout = async () => {
395
+ setLocked(true);
308
396
  const response = await fetch("/api/payments/subscription", {
309
397
  method: "POST",
310
398
  headers: { "content-type": "application/json" },
311
- body: JSON.stringify({ applicationId: props.applicationId, refundPolicyAck: true, quoteDigest: quote.digest })
399
+ body: JSON.stringify({
400
+ applicationId: props.applicationId,
401
+ refundPolicyAck: true,
402
+ quoteDigest: quote.digest,
403
+ ...quote.namedSeat ? { seatTermsAck: true } : {}
404
+ })
312
405
  });
313
406
  if (!response.ok) {
314
407
  if (response.status === 409) refresh();
@@ -317,45 +410,86 @@ function MembershipPaymentStep(props) {
317
410
  return response.json();
318
411
  };
319
412
  const amount = (cents) => new Intl.NumberFormat("en-US", { style: "currency", currency: quote.currency }).format(cents / 100);
320
- return /* @__PURE__ */ jsxs3(Fragment2, { children: [
321
- /* @__PURE__ */ jsxs3("section", { className: "payment-quote", "aria-label": "Membership price", children: [
322
- /* @__PURE__ */ jsx3("h3", { children: quote.tierName }),
323
- quote.founding ? /* @__PURE__ */ jsx3("p", { className: "payment-founding", role: "note", "aria-label": "Founding member", children: copy.foundingMember }) : null,
413
+ const changeSeat = async (namedSeat) => {
414
+ const response = await fetch(`/api/payments/quote?application=${encodeURIComponent(props.applicationId)}`, {
415
+ method: "POST",
416
+ cache: "no-store",
417
+ headers: { "content-type": "application/json" },
418
+ body: JSON.stringify({ namedSeat })
419
+ });
420
+ if (!response.ok) {
421
+ if (response.status === 409) refresh();
422
+ throw new Error(response.status === 400 ? "Enter a different recipient's name and valid email." : "Could not update your total. Reload payment terms and try again.");
423
+ }
424
+ const value = await response.json();
425
+ if (value.applicationId !== props.applicationId || !/^[a-f0-9]{64}$/.test(value.digest)) throw new Error(copy.setupFailed);
426
+ setQuote(value);
427
+ setEditing(false);
428
+ setSeatTerms(false);
429
+ setPrefillConsumed(true);
430
+ };
431
+ return /* @__PURE__ */ jsxs4(Fragment3, { children: [
432
+ quote.seatOffer ? /* @__PURE__ */ jsx4(
433
+ CheckoutSeatChoice,
434
+ {
435
+ quote,
436
+ locked,
437
+ onChange: changeSeat,
438
+ initial: quote.namedSeat || locked || prefillConsumed ? void 0 : props.initialNamedSeat,
439
+ onEditing: setEditing
440
+ },
441
+ quote.digest
442
+ ) : null,
443
+ /* @__PURE__ */ jsxs4("section", { className: "payment-quote", "aria-label": "Membership price", children: [
444
+ /* @__PURE__ */ jsx4("h3", { children: quote.tierName }),
445
+ quote.founding ? /* @__PURE__ */ jsx4("p", { className: "payment-founding", role: "note", "aria-label": "Founding member", children: copy.foundingMember }) : null,
324
446
  props.renderPriceLines ? props.renderPriceLines({
325
447
  ...quote.lineItems,
326
448
  ...quote.founding ? { founding: quote.founding } : {},
327
449
  ...quote.presentation ? { presentation: quote.presentation } : {}
328
- }) : /* @__PURE__ */ jsxs3("dl", { children: [
329
- quote.lineItems.discountCents > 0 && !quote.founding && quote.presentation ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
330
- /* @__PURE__ */ jsx3("dt", { children: copy.standardRate }),
331
- /* @__PURE__ */ jsxs3("dd", { children: [
450
+ }) : /* @__PURE__ */ jsxs4("dl", { children: [
451
+ quote.lineItems.discountCents > 0 && !quote.founding && quote.presentation ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
452
+ /* @__PURE__ */ jsx4("dt", { children: copy.standardRate }),
453
+ /* @__PURE__ */ jsxs4("dd", { children: [
332
454
  amount(quote.lineItems.standardCents),
333
455
  " per ",
334
456
  quote.interval
335
457
  ] }),
336
- /* @__PURE__ */ jsx3("dt", { children: copy.yourRate }),
337
- /* @__PURE__ */ jsxs3("dd", { children: [
338
- amount(quote.lineItems.dueTodayCents),
458
+ /* @__PURE__ */ jsx4("dt", { children: copy.yourRate }),
459
+ /* @__PURE__ */ jsxs4("dd", { children: [
460
+ amount(quote.lineItems.dueTodayCents - (quote.lineItems.namedSeatCents ?? 0)),
339
461
  " per ",
340
462
  quote.interval
341
463
  ] })
342
- ] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
343
- /* @__PURE__ */ jsx3("dt", { children: "Membership price" }),
344
- /* @__PURE__ */ jsxs3("dd", { children: [
464
+ ] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
465
+ /* @__PURE__ */ jsx4("dt", { children: "Membership price" }),
466
+ /* @__PURE__ */ jsxs4("dd", { children: [
345
467
  amount(quote.lineItems.standardCents),
346
468
  " per ",
347
469
  quote.interval
348
470
  ] }),
349
- quote.lineItems.discountCents > 0 ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
350
- /* @__PURE__ */ jsx3("dt", { children: quote.founding ? copy.foundingDiscount : "Discount" }),
351
- /* @__PURE__ */ jsx3("dd", { children: amount(quote.lineItems.discountCents) })
471
+ quote.lineItems.discountCents > 0 ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
472
+ /* @__PURE__ */ jsx4("dt", { children: quote.founding ? copy.foundingDiscount : "Discount" }),
473
+ /* @__PURE__ */ jsx4("dd", { children: amount(quote.lineItems.discountCents) })
352
474
  ] }) : null
353
475
  ] }),
354
- /* @__PURE__ */ jsx3("dt", { children: "Due today" }),
355
- /* @__PURE__ */ jsx3("dd", { children: amount(quote.lineItems.dueTodayCents) })
476
+ quote.namedSeat ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
477
+ /* @__PURE__ */ jsx4("dt", { children: "Additional member" }),
478
+ /* @__PURE__ */ jsx4("dd", { children: quote.lineItems.namedSeatCents === 0 ? "Included" : amount(quote.lineItems.namedSeatCents) })
479
+ ] }) : null,
480
+ /* @__PURE__ */ jsx4("dt", { children: "Due today" }),
481
+ /* @__PURE__ */ jsx4("dd", { children: amount(quote.lineItems.dueTodayCents) })
356
482
  ] }),
357
- quote.commercial ? /* @__PURE__ */ jsxs3("div", { role: "note", "aria-label": "Renewal terms", children: [
358
- quote.commercial.initialTermEndsAt !== void 0 ? /* @__PURE__ */ jsxs3("p", { children: [
483
+ quote.namedSeat ? /* @__PURE__ */ jsxs4("p", { children: [
484
+ "For ",
485
+ quote.namedSeat.recipientName,
486
+ " \xB7 ",
487
+ quote.namedSeat.recipientEmail,
488
+ ".",
489
+ props.renderPriceLines ? ` Additional member: ${quote.lineItems.namedSeatCents === 0 ? "included" : amount(quote.lineItems.namedSeatCents)} in the total above.` : ""
490
+ ] }) : null,
491
+ quote.commercial ? /* @__PURE__ */ jsxs4("div", { role: "note", "aria-label": "Renewal terms", children: [
492
+ quote.commercial.initialTermEndsAt !== void 0 ? /* @__PURE__ */ jsxs4("p", { children: [
359
493
  "First renewal: ",
360
494
  new Intl.DateTimeFormat("en-US", {
361
495
  dateStyle: "long",
@@ -363,19 +497,31 @@ function MembershipPaymentStep(props) {
363
497
  }).format(quote.commercial.initialTermEndsAt),
364
498
  "."
365
499
  ] }) : null,
366
- /* @__PURE__ */ jsxs3("p", { children: [
500
+ /* @__PURE__ */ jsxs4("p", { children: [
367
501
  "Renews automatically at ",
368
502
  amount(quote.commercial.renewalCents),
369
503
  " per ",
370
504
  quote.interval,
371
505
  " unless canceled before renewal."
372
506
  ] }),
373
- quote.commercial.discountDuration === "first_term" ? /* @__PURE__ */ jsx3("p", { children: "The discount applies to your first paid term only." }) : null,
374
- quote.commercial.discountDuration === "while_active" ? /* @__PURE__ */ jsx3("p", { children: "The discounted rate continues while this membership stays active." }) : null
507
+ quote.commercial.discountDuration === "first_term" ? /* @__PURE__ */ jsx4("p", { children: "The discount applies to your first paid term only." }) : null,
508
+ quote.commercial.discountDuration === "while_active" ? /* @__PURE__ */ jsx4("p", { children: "The discounted rate continues while this membership stays active." }) : null
375
509
  ] }) : null,
376
- quote.trustCopy ? /* @__PURE__ */ jsx3("p", { className: "pay-trust", children: quote.trustCopy }) : null
510
+ quote.trustCopy ? /* @__PURE__ */ jsx4("p", { className: "pay-trust", children: quote.trustCopy }) : null
377
511
  ] }),
378
- /* @__PURE__ */ jsx3(
512
+ quote.namedSeat && !editing ? /* @__PURE__ */ jsxs4("label", { className: "journey-consent", children: [
513
+ /* @__PURE__ */ jsx4(
514
+ "input",
515
+ {
516
+ type: "checkbox",
517
+ checked: seatTerms,
518
+ disabled: locked,
519
+ onChange: (event) => setSeatTerms(event.currentTarget.checked)
520
+ }
521
+ ),
522
+ "I agree to the additional-member terms and renewal with my membership."
523
+ ] }) : null,
524
+ !editing && (!quote.namedSeat || seatTerms) ? /* @__PURE__ */ jsx4(
379
525
  PaymentStep,
380
526
  {
381
527
  ...props,
@@ -383,13 +529,14 @@ function MembershipPaymentStep(props) {
383
529
  merchantDisclosureText: quote.merchantDisclosureText,
384
530
  renderPriceLines: void 0,
385
531
  startCheckout
386
- }
387
- )
532
+ },
533
+ quote.digest
534
+ ) : editing ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Update the total to continue to payment." }) : null
388
535
  ] });
389
536
  }
390
537
 
391
538
  // src/ui/journey-frame.tsx
392
- import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
539
+ import { jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
393
540
  var styles = `
394
541
  .chapter-journey{color:var(--ui-text,#202827);font-family:var(--ui-font-sans,inherit);line-height:1.65;max-width:46rem;margin-inline:auto;min-width:0}
395
542
  .chapter-journey *{box-sizing:border-box}
@@ -424,21 +571,21 @@ var styles = `
424
571
  @media(max-width:520px){.chapter-journey .journey-actions>*{width:100%}.chapter-journey .journey-summary{grid-template-columns:1fr}.chapter-journey .journey-summary dd{text-align:left}.chapter-journey :where(.card,.join-form,.payment-quote,.join-book){padding:1.25rem}}
425
572
  `;
426
573
  function JourneyFrame({ children }) {
427
- return /* @__PURE__ */ jsxs4("div", { className: "chapter-journey", children: [
428
- /* @__PURE__ */ jsx4("style", { children: styles }),
574
+ return /* @__PURE__ */ jsxs5("div", { className: "chapter-journey", children: [
575
+ /* @__PURE__ */ jsx5("style", { children: styles }),
429
576
  children
430
577
  ] });
431
578
  }
432
579
 
433
580
  // src/ui/member-restart.tsx
434
- import { jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
581
+ import { jsx as jsx6, jsxs as jsxs6 } from "preact/jsx-runtime";
435
582
  function MemberRestart(props) {
436
- const [id, setId] = useState4(props.applicationId);
437
- const [busy, setBusy] = useState4(false);
438
- const [error, setError] = useState4("");
439
- const [paid, setPaid] = useState4(false);
440
- const [checking, setChecking] = useState4(false);
441
- const [revision, setRevision] = useState4(0);
583
+ const [id, setId] = useState5(props.applicationId);
584
+ const [busy, setBusy] = useState5(false);
585
+ const [error, setError] = useState5("");
586
+ const [paid, setPaid] = useState5(false);
587
+ const [checking, setChecking] = useState5(false);
588
+ const [revision, setRevision] = useState5(0);
442
589
  useEffect2(() => {
443
590
  if (!paid) return;
444
591
  let live = true, timer, attempt = 0;
@@ -476,40 +623,40 @@ function MemberRestart(props) {
476
623
  setBusy(false);
477
624
  }
478
625
  };
479
- return /* @__PURE__ */ jsx5(JourneyFrame, { children: /* @__PURE__ */ jsxs5("section", { className: "card", "aria-label": "Restart membership", children: [
480
- /* @__PURE__ */ jsx5("p", { className: "card-label", children: "Welcome back" }),
481
- /* @__PURE__ */ jsx5("h2", { children: "Restart your membership" }),
482
- /* @__PURE__ */ jsx5("p", { children: "Your account is ready, and your previous approval still counts. No new application or interview is needed." }),
483
- /* @__PURE__ */ jsxs5("dl", { className: "journey-summary", children: [
484
- /* @__PURE__ */ jsx5("dt", { children: "Name" }),
485
- /* @__PURE__ */ jsx5("dd", { children: [props.application.firstName, props.application.lastName].filter(Boolean).join(" ") }),
486
- /* @__PURE__ */ jsx5("dt", { children: "Email" }),
487
- /* @__PURE__ */ jsx5("dd", { children: props.application.email })
626
+ return /* @__PURE__ */ jsx6(JourneyFrame, { children: /* @__PURE__ */ jsxs6("section", { className: "card", "aria-label": "Restart membership", children: [
627
+ /* @__PURE__ */ jsx6("p", { className: "card-label", children: "Welcome back" }),
628
+ /* @__PURE__ */ jsx6("h2", { children: "Restart your membership" }),
629
+ /* @__PURE__ */ jsx6("p", { children: "Your account is ready, and your previous approval still counts. No new application or interview is needed." }),
630
+ /* @__PURE__ */ jsxs6("dl", { className: "journey-summary", children: [
631
+ /* @__PURE__ */ jsx6("dt", { children: "Name" }),
632
+ /* @__PURE__ */ jsx6("dd", { children: [props.application.firstName, props.application.lastName].filter(Boolean).join(" ") }),
633
+ /* @__PURE__ */ jsx6("dt", { children: "Email" }),
634
+ /* @__PURE__ */ jsx6("dd", { children: props.application.email })
488
635
  ] }),
489
- paid ? /* @__PURE__ */ jsxs5("div", { role: "status", children: [
490
- /* @__PURE__ */ jsx5("h3", { children: "Confirming your membership" }),
491
- /* @__PURE__ */ jsx5("p", { children: "We\u2019re waiting for payment confirmation. Your membership will open here as soon as it arrives." }),
492
- !checking ? /* @__PURE__ */ jsx5("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Check membership" }) : null
493
- ] }) : id ? /* @__PURE__ */ jsx5(MembershipPaymentStep, { applicationId: id, refundPolicyText: "", onPaid: () => setPaid(true) }) : /* @__PURE__ */ jsx5("button", { type: "button", disabled: busy, onClick: () => void start(), children: busy ? "Preparing your membership\u2026" : "Review membership and payment" }),
494
- error ? /* @__PURE__ */ jsx5("p", { role: "alert", children: error }) : null
636
+ paid ? /* @__PURE__ */ jsxs6("div", { role: "status", children: [
637
+ /* @__PURE__ */ jsx6("h3", { children: "Confirming your membership" }),
638
+ /* @__PURE__ */ jsx6("p", { children: "We\u2019re waiting for payment confirmation. Your membership will open here as soon as it arrives." }),
639
+ !checking ? /* @__PURE__ */ jsx6("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Check membership" }) : null
640
+ ] }) : id ? /* @__PURE__ */ jsx6(MembershipPaymentStep, { applicationId: id, refundPolicyText: "", onPaid: () => setPaid(true) }) : /* @__PURE__ */ jsx6("button", { type: "button", disabled: busy, onClick: () => void start(), children: busy ? "Preparing your membership\u2026" : "Review membership and payment" }),
641
+ error ? /* @__PURE__ */ jsx6("p", { role: "alert", children: error }) : null
495
642
  ] }) });
496
643
  }
497
644
 
498
645
  // src/ui/members.tsx
499
- import { useEffect as useEffect6, useState as useState9 } from "preact/hooks";
646
+ import { useEffect as useEffect6, useState as useState10 } from "preact/hooks";
500
647
 
501
648
  // src/ui/reschedule.tsx
502
- import { useState as useState5 } from "preact/hooks";
503
- import { jsx as jsx6, jsxs as jsxs6 } from "preact/jsx-runtime";
649
+ import { useState as useState6 } from "preact/hooks";
650
+ import { jsx as jsx7, jsxs as jsxs7 } from "preact/jsx-runtime";
504
651
  function Rescheduler(props) {
505
652
  const inheritedCopy = useChapterCopy();
506
653
  const copy = props.copy ?? inheritedCopy.members.reschedule;
507
654
  const { api, applicationId, timezone, onRescheduled, label = copy.changeTime } = props;
508
- const [open, setOpen] = useState5(false);
509
- const [slots, setSlots] = useState5(null);
510
- const [tz, setTz] = useState5(timezone);
511
- const [busy, setBusy] = useState5(false);
512
- const [msg, setMsg] = useState5(null);
655
+ const [open, setOpen] = useState6(false);
656
+ const [slots, setSlots] = useState6(null);
657
+ const [tz, setTz] = useState6(timezone);
658
+ const [busy, setBusy] = useState6(false);
659
+ const [msg, setMsg] = useState6(null);
513
660
  const start = async () => {
514
661
  setOpen(true);
515
662
  setSlots(null);
@@ -542,7 +689,7 @@ function Rescheduler(props) {
542
689
  }
543
690
  };
544
691
  if (!open) {
545
- return /* @__PURE__ */ jsx6("p", { className: "meeting-note", children: /* @__PURE__ */ jsx6(
692
+ return /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: /* @__PURE__ */ jsx7(
546
693
  "a",
547
694
  {
548
695
  href: "#",
@@ -554,8 +701,8 @@ function Rescheduler(props) {
554
701
  }
555
702
  ) });
556
703
  }
557
- return /* @__PURE__ */ jsxs6("div", { className: "msched", children: [
558
- slots === null ? /* @__PURE__ */ jsx6("p", { className: "meeting-note", children: copy.loading }) : slots.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "meeting-note", children: msg ?? copy.noTimes }) : /* @__PURE__ */ jsx6(
704
+ return /* @__PURE__ */ jsxs7("div", { className: "msched", children: [
705
+ slots === null ? /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: copy.loading }) : slots.length === 0 ? /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: msg ?? copy.noTimes }) : /* @__PURE__ */ jsx7(
559
706
  SlotPicker,
560
707
  {
561
708
  slots,
@@ -564,9 +711,9 @@ function Rescheduler(props) {
564
711
  onPick: (s) => void pick(s)
565
712
  }
566
713
  ),
567
- busy ? /* @__PURE__ */ jsx6("p", { className: "meeting-note", children: copy.rescheduling }) : null,
568
- msg && slots && slots.length > 0 ? /* @__PURE__ */ jsx6("p", { className: "meeting-note error", children: msg }) : null,
569
- /* @__PURE__ */ jsx6("p", { className: "meeting-note", children: /* @__PURE__ */ jsx6(
714
+ busy ? /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: copy.rescheduling }) : null,
715
+ msg && slots && slots.length > 0 ? /* @__PURE__ */ jsx7("p", { className: "meeting-note error", children: msg }) : null,
716
+ /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: /* @__PURE__ */ jsx7(
570
717
  "a",
571
718
  {
572
719
  href: "#",
@@ -581,31 +728,31 @@ function Rescheduler(props) {
581
728
  }
582
729
 
583
730
  // src/ui/member-gifts.tsx
584
- import { useEffect as useEffect3, useRef as useRef2, useState as useState6 } from "preact/hooks";
731
+ import { useEffect as useEffect3, useRef as useRef2, useState as useState7 } from "preact/hooks";
585
732
 
586
733
  // src/ui/gift-offer-cards.tsx
587
- import { jsx as jsx7, jsxs as jsxs7 } from "preact/jsx-runtime";
734
+ import { jsx as jsx8, jsxs as jsxs8 } from "preact/jsx-runtime";
588
735
  var price = (cents, currency) => currency === "usd" ? fmtMoney(cents) : new Intl.NumberFormat(void 0, { style: "currency", currency: currency.toUpperCase() }).format(cents / 100);
589
736
  function GiftOfferCards(props) {
590
737
  const mode = props.mode ?? "preview";
591
- return /* @__PURE__ */ jsx7("section", { className: "chapter-gift-offers", "aria-label": props.ariaLabel ?? "Gift options", children: props.offers.map((offer) => /* @__PURE__ */ jsxs7("article", { className: "card chapter-gift-offer", "data-offer-id": offer.id, children: [
592
- /* @__PURE__ */ jsx7("div", { className: "card-label", children: offer.title }),
593
- /* @__PURE__ */ jsx7("p", { children: offer.description }),
594
- /* @__PURE__ */ jsxs7("p", { className: "meeting-date", children: [
738
+ return /* @__PURE__ */ jsx8("section", { className: "chapter-gift-offers", "aria-label": props.ariaLabel ?? "Gift options", children: props.offers.map((offer) => /* @__PURE__ */ jsxs8("article", { className: "card chapter-gift-offer", "data-offer-id": offer.id, children: [
739
+ /* @__PURE__ */ jsx8("div", { className: "card-label", children: offer.title }),
740
+ /* @__PURE__ */ jsx8("p", { children: offer.description }),
741
+ /* @__PURE__ */ jsxs8("p", { className: "meeting-date", children: [
595
742
  price(offer.priceCents, offer.currency),
596
743
  offer.billingMode === "subscription" ? " recurring" : ""
597
744
  ] }),
598
- mode === "select" ? /* @__PURE__ */ jsx7("button", { type: "button", className: "btn secondary", "aria-pressed": props.selectedOfferId === offer.id, onClick: () => props.onSelect?.(offer.id), children: offer.ctaLabel }) : /* @__PURE__ */ jsx7("span", { className: "btn secondary", "aria-disabled": "true", children: offer.ctaLabel })
745
+ mode === "select" ? /* @__PURE__ */ jsx8("button", { type: "button", className: "btn secondary", "aria-pressed": props.selectedOfferId === offer.id, onClick: () => props.onSelect?.(offer.id), children: offer.ctaLabel }) : /* @__PURE__ */ jsx8("span", { className: "btn secondary", "aria-disabled": "true", children: offer.ctaLabel })
599
746
  ] }, offer.id)) });
600
747
  }
601
748
 
602
749
  // src/ui/member-gifts.tsx
603
- import { jsx as jsx8, jsxs as jsxs8 } from "preact/jsx-runtime";
750
+ import { jsx as jsx9, jsxs as jsxs9 } from "preact/jsx-runtime";
604
751
  function GiftPurchases(props) {
605
- const [data, setData] = useState6(null);
606
- const [selected, setSelected] = useState6(null);
607
- const [code, setCode] = useState6("");
608
- const [message, setMessage] = useState6("");
752
+ const [data, setData] = useState7(null);
753
+ const [selected, setSelected] = useState7(null);
754
+ const [code, setCode] = useState7("");
755
+ const [message, setMessage] = useState7("");
609
756
  const purchaseId = useRef2(crypto.randomUUID());
610
757
  const load = async () => setData(await props.api("/api/gifts"));
611
758
  useEffect3(() => {
@@ -623,16 +770,16 @@ function GiftPurchases(props) {
623
770
  if (!data) return null;
624
771
  if (data.offers.length === 0 && data.claims.length === 0) return null;
625
772
  const offer = data.offers.find((item) => item.id === selected);
626
- return /* @__PURE__ */ jsxs8("section", { className: "member-gifts", children: [
627
- data.offers.length ? /* @__PURE__ */ jsxs8("div", { className: "card", children: [
628
- /* @__PURE__ */ jsx8("div", { className: "card-label", children: props.copy.title }),
629
- /* @__PURE__ */ jsx8("p", { children: props.copy.body }),
630
- /* @__PURE__ */ jsx8(GiftOfferCards, { offers: data.offers, mode: "select", selectedOfferId: selected, onSelect: (id) => {
773
+ return /* @__PURE__ */ jsxs9("section", { className: "member-gifts", children: [
774
+ data.offers.length ? /* @__PURE__ */ jsxs9("div", { className: "card", children: [
775
+ /* @__PURE__ */ jsx9("div", { className: "card-label", children: props.copy.title }),
776
+ /* @__PURE__ */ jsx9("p", { children: props.copy.body }),
777
+ /* @__PURE__ */ jsx9(GiftOfferCards, { offers: data.offers, mode: "select", selectedOfferId: selected, onSelect: (id) => {
631
778
  setSelected(id);
632
779
  setCode("");
633
780
  purchaseId.current = crypto.randomUUID();
634
781
  } }),
635
- offer ? /* @__PURE__ */ jsx8(
782
+ offer ? /* @__PURE__ */ jsx9(
636
783
  PaymentStep,
637
784
  {
638
785
  applicationId: purchaseId.current,
@@ -652,27 +799,27 @@ function GiftPurchases(props) {
652
799
  }
653
800
  }
654
801
  ) : null,
655
- code ? /* @__PURE__ */ jsxs8("div", { className: "gift-code-once", children: [
656
- /* @__PURE__ */ jsx8("output", { children: code }),
657
- /* @__PURE__ */ jsx8("p", { children: props.copy.saveCode })
802
+ code ? /* @__PURE__ */ jsxs9("div", { className: "gift-code-once", children: [
803
+ /* @__PURE__ */ jsx9("output", { children: code }),
804
+ /* @__PURE__ */ jsx9("p", { children: props.copy.saveCode })
658
805
  ] }) : null
659
806
  ] }) : null,
660
- /* @__PURE__ */ jsxs8("div", { className: "card", children: [
661
- /* @__PURE__ */ jsx8("div", { className: "card-label", children: props.copy.purchases }),
662
- data.claims.length ? data.claims.map((claim) => /* @__PURE__ */ jsxs8("div", { className: "member-row", children: [
663
- /* @__PURE__ */ jsx8("span", { children: claim.offerId }),
664
- /* @__PURE__ */ jsx8("span", { children: props.copy[claim.status] }),
665
- claim.status === "pending" ? /* @__PURE__ */ jsx8("button", { className: "btn secondary mini", onClick: () => void rotate(claim.id), children: props.copy.rotate }) : null
666
- ] }, claim.id)) : /* @__PURE__ */ jsx8("p", { children: props.copy.noPurchases }),
667
- message ? /* @__PURE__ */ jsx8("p", { role: "status", children: message }) : null
807
+ /* @__PURE__ */ jsxs9("div", { className: "card", children: [
808
+ /* @__PURE__ */ jsx9("div", { className: "card-label", children: props.copy.purchases }),
809
+ data.claims.length ? data.claims.map((claim) => /* @__PURE__ */ jsxs9("div", { className: "member-row", children: [
810
+ /* @__PURE__ */ jsx9("span", { children: claim.offerId }),
811
+ /* @__PURE__ */ jsx9("span", { children: props.copy[claim.status] }),
812
+ claim.status === "pending" ? /* @__PURE__ */ jsx9("button", { className: "btn secondary mini", onClick: () => void rotate(claim.id), children: props.copy.rotate }) : null
813
+ ] }, claim.id)) : /* @__PURE__ */ jsx9("p", { children: props.copy.noPurchases }),
814
+ message ? /* @__PURE__ */ jsx9("p", { role: "status", children: message }) : null
668
815
  ] })
669
816
  ] });
670
817
  }
671
818
  var MemberGifts = GiftPurchases;
672
819
 
673
820
  // src/ui/member-named-seat.tsx
674
- import { useEffect as useEffect4, useState as useState7 } from "preact/hooks";
675
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs9 } from "preact/jsx-runtime";
821
+ import { useEffect as useEffect4, useState as useState8 } from "preact/hooks";
822
+ import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs10 } from "preact/jsx-runtime";
676
823
  var NAMED_SEAT_RECIPIENT_WORDS = {
677
824
  payment_pending: "payment in progress",
678
825
  invited: "invited, waiting for them to accept",
@@ -685,7 +832,7 @@ var NAMED_SEAT_RECIPIENT_WORDS = {
685
832
  var day = (at) => new Date(at).toLocaleDateString("en-US", { timeZone: "UTC" });
686
833
  function NamedSeatRecipientLine({ seat }) {
687
834
  const words = NAMED_SEAT_RECIPIENT_WORDS[seat.recipientState] ?? seat.status.replaceAll("_", " ");
688
- return /* @__PURE__ */ jsxs9("p", { className: "member-named-seat-recipient", children: [
835
+ return /* @__PURE__ */ jsxs10("p", { className: "member-named-seat-recipient", children: [
689
836
  seat.recipientName,
690
837
  " \xB7 ",
691
838
  seat.recipientEmail,
@@ -695,9 +842,9 @@ function NamedSeatRecipientLine({ seat }) {
695
842
  ] });
696
843
  }
697
844
  function NamedSeatPurchase({ api }) {
698
- const [data, setData] = useState7(null), [error, setError] = useState7("");
699
- const [name, setName] = useState7(""), [email, setEmail] = useState7(""), [reviewing, setReviewing] = useState7(false);
700
- const [terms, setTerms] = useState7(false), [pending, setPending] = useState7(false), [granting, setGranting] = useState7(false);
845
+ const [data, setData] = useState8(null), [error, setError] = useState8("");
846
+ const [name, setName] = useState8(""), [email, setEmail] = useState8(""), [reviewing, setReviewing] = useState8(false);
847
+ const [terms, setTerms] = useState8(false), [pending, setPending] = useState8(false), [granting, setGranting] = useState8(false);
701
848
  const load = async () => {
702
849
  try {
703
850
  const value = await api("/api/named-seat");
@@ -734,13 +881,13 @@ function NamedSeatPurchase({ api }) {
734
881
  }
735
882
  };
736
883
  const money = data ? new Intl.NumberFormat("en-US", { style: "currency", currency: data.currency }).format(data.amountCents / 100) : "";
737
- return /* @__PURE__ */ jsx9(JourneyFrame, { children: /* @__PURE__ */ jsxs9("section", { className: "card member-named-seat", "aria-label": "Named additional seat", children: [
738
- /* @__PURE__ */ jsx9("h2", { children: "Named additional seat" }),
739
- error ? /* @__PURE__ */ jsx9("p", { role: "alert", children: error }) : null,
740
- data ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
741
- data.seat ? /* @__PURE__ */ jsx9(NamedSeatRecipientLine, { seat: data.seat }) : null,
742
- data.eligible ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
743
- /* @__PURE__ */ jsxs9("p", { children: [
884
+ return /* @__PURE__ */ jsx10(JourneyFrame, { children: /* @__PURE__ */ jsxs10("section", { className: "card member-named-seat", "aria-label": "Named additional seat", children: [
885
+ /* @__PURE__ */ jsx10("h2", { children: "Named additional seat" }),
886
+ error ? /* @__PURE__ */ jsx10("p", { role: "alert", children: error }) : null,
887
+ data ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
888
+ data.seat ? /* @__PURE__ */ jsx10(NamedSeatRecipientLine, { seat: data.seat }) : null,
889
+ data.eligible ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
890
+ /* @__PURE__ */ jsxs10("p", { children: [
744
891
  data.included ? "Included with your membership at no charge." : `${money} paid in full now.`,
745
892
  " This seat ",
746
893
  data.autoRenew ? "renews with your primary membership" : "ends with your primary membership",
@@ -751,39 +898,39 @@ function NamedSeatPurchase({ api }) {
751
898
  " ",
752
899
  "It belongs to one named person and cannot be reassigned."
753
900
  ] }),
754
- /* @__PURE__ */ jsx9("p", { children: "The recipient must accept and complete their own application and any required interview. The seat stays open for them while your membership is paid; it is not refunded automatically. Contact the chapter if you need a refund." }),
755
- !reviewing ? /* @__PURE__ */ jsxs9("form", { onSubmit: (event) => {
901
+ /* @__PURE__ */ jsx10("p", { children: "The recipient must accept and complete their own application and any required interview. The seat stays open for them while your membership is paid; it is not refunded automatically. Contact the chapter if you need a refund." }),
902
+ !reviewing ? /* @__PURE__ */ jsxs10("form", { onSubmit: (event) => {
756
903
  event.preventDefault();
757
904
  setReviewing(true);
758
905
  setTerms(false);
759
906
  }, children: [
760
- /* @__PURE__ */ jsxs9("label", { children: [
907
+ /* @__PURE__ */ jsxs10("label", { children: [
761
908
  "Recipient name",
762
- /* @__PURE__ */ jsx9("input", { required: true, maxLength: 160, value: name, disabled: Boolean(data.seat), onInput: (event) => setName(event.currentTarget.value) })
909
+ /* @__PURE__ */ jsx10("input", { required: true, maxLength: 160, value: name, disabled: Boolean(data.seat), onInput: (event) => setName(event.currentTarget.value) })
763
910
  ] }),
764
- /* @__PURE__ */ jsxs9("label", { children: [
911
+ /* @__PURE__ */ jsxs10("label", { children: [
765
912
  "Recipient email",
766
- /* @__PURE__ */ jsx9("input", { required: true, type: "email", maxLength: 254, value: email, disabled: Boolean(data.seat), onInput: (event) => setEmail(event.currentTarget.value) })
913
+ /* @__PURE__ */ jsx10("input", { required: true, type: "email", maxLength: 254, value: email, disabled: Boolean(data.seat), onInput: (event) => setEmail(event.currentTarget.value) })
767
914
  ] }),
768
- /* @__PURE__ */ jsx9("button", { className: "btn primary", type: "submit", children: "Review named seat" })
769
- ] }) : /* @__PURE__ */ jsxs9(Fragment3, { children: [
770
- /* @__PURE__ */ jsxs9("p", { children: [
915
+ /* @__PURE__ */ jsx10("button", { className: "btn primary", type: "submit", children: "Review named seat" })
916
+ ] }) : /* @__PURE__ */ jsxs10(Fragment4, { children: [
917
+ /* @__PURE__ */ jsxs10("p", { children: [
771
918
  "For ",
772
919
  name,
773
920
  " \xB7 ",
774
921
  email
775
922
  ] }),
776
- /* @__PURE__ */ jsx9("button", { className: "btn secondary", type: "button", onClick: () => {
923
+ /* @__PURE__ */ jsx10("button", { className: "btn secondary", type: "button", onClick: () => {
777
924
  setReviewing(false);
778
925
  setTerms(false);
779
926
  void load();
780
927
  }, children: "Back to recipient" }),
781
- /* @__PURE__ */ jsxs9("label", { className: "journey-consent", children: [
782
- /* @__PURE__ */ jsx9("input", { type: "checkbox", checked: terms, onChange: (event) => setTerms(event.currentTarget.checked) }),
783
- /* @__PURE__ */ jsx9("span", { children: data.included ? "I agree to the seat terms and the refund policy; the seat is included with my membership and follows its renewal." : data.autoRenew ? "I agree to the full initial payment and automatic renewal with my membership; I can cancel renewal." : "I agree to the full initial payment and the displayed end date, with no automatic renewal while my membership renewal is canceled." })
928
+ /* @__PURE__ */ jsxs10("label", { className: "journey-consent", children: [
929
+ /* @__PURE__ */ jsx10("input", { type: "checkbox", checked: terms, onChange: (event) => setTerms(event.currentTarget.checked) }),
930
+ /* @__PURE__ */ jsx10("span", { children: data.included ? "I agree to the seat terms and the refund policy; the seat is included with my membership and follows its renewal." : data.autoRenew ? "I agree to the full initial payment and automatic renewal with my membership; I can cancel renewal." : "I agree to the full initial payment and the displayed end date, with no automatic renewal while my membership renewal is canceled." })
784
931
  ] }),
785
- terms && data.included ? /* @__PURE__ */ jsx9("button", { className: "btn primary", type: "button", disabled: granting, onClick: () => void grant(), children: granting ? "Sending the invitation\u2026" : "Send the invitation" }) : null,
786
- terms && !data.included ? /* @__PURE__ */ jsx9(
932
+ terms && data.included ? /* @__PURE__ */ jsx10("button", { className: "btn primary", type: "button", disabled: granting, onClick: () => void grant(), children: granting ? "Sending the invitation\u2026" : "Send the invitation" }) : null,
933
+ terms && !data.included ? /* @__PURE__ */ jsx10(
787
934
  PaymentStep,
788
935
  {
789
936
  applicationId: data.membershipId,
@@ -798,17 +945,17 @@ function NamedSeatPurchase({ api }) {
798
945
  }
799
946
  ) : null
800
947
  ] })
801
- ] }) : !data.seat ? /* @__PURE__ */ jsx9("p", { children: data.purchaseWindowed === false ? "An additional seat can be purchased for as long as your membership stays paid." : `Additional seats can be purchased until ${day(data.purchaseEndsAt)}.` }) : null,
802
- pending ? /* @__PURE__ */ jsx9("p", { role: "status", children: "Payment confirmation is being reconciled. The recipient\u2019s access begins only after their own acceptance and approval." }) : null
803
- ] }) : !error ? /* @__PURE__ */ jsx9("p", { children: "Loading your seat terms\u2026" }) : null,
804
- /* @__PURE__ */ jsx9("button", { className: "btn secondary", onClick: () => void load(), children: "Refresh seat status" })
948
+ ] }) : !data.seat ? /* @__PURE__ */ jsx10("p", { children: data.purchaseWindowed === false ? "An additional seat can be purchased for as long as your membership stays paid." : `Additional seats can be purchased until ${day(data.purchaseEndsAt)}.` }) : null,
949
+ pending ? /* @__PURE__ */ jsx10("p", { role: "status", children: "Payment confirmation is being reconciled. The recipient\u2019s access begins only after their own acceptance and approval." }) : null
950
+ ] }) : !error ? /* @__PURE__ */ jsx10("p", { children: "Loading your seat terms\u2026" }) : null,
951
+ /* @__PURE__ */ jsx10("button", { className: "btn secondary", onClick: () => void load(), children: "Refresh seat status" })
805
952
  ] }) });
806
953
  }
807
954
 
808
955
  // src/ui/member-content.tsx
809
- import { useEffect as useEffect5, useMemo as useMemo2, useState as useState8 } from "preact/hooks";
956
+ import { useEffect as useEffect5, useMemo as useMemo2, useState as useState9 } from "preact/hooks";
810
957
  import { Markdown } from "@odla-ai/ui/components";
811
- import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs10 } from "preact/jsx-runtime";
958
+ import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs11 } from "preact/jsx-runtime";
812
959
  var pageLabel = (page) => `${page.title}${page.access === "locked" ? " \xB7 Locked" : ""}`;
813
960
  function MemberContentArea(props) {
814
961
  const {
@@ -816,12 +963,12 @@ function MemberContentArea(props) {
816
963
  path = "/api/member-content",
817
964
  upsellHref,
818
965
  onUpsell,
819
- loadingContent = /* @__PURE__ */ jsx10("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
820
- emptyContent = /* @__PURE__ */ jsx10("p", { className: "meeting-note", children: "No member pages have been published yet." })
966
+ loadingContent = /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
967
+ emptyContent = /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: "No member pages have been published yet." })
821
968
  } = props;
822
- const [data, setData] = useState8(props.initialData ?? null);
823
- const [error, setError] = useState8(null);
824
- const [selectedId, setSelectedId] = useState8(
969
+ const [data, setData] = useState9(props.initialData ?? null);
970
+ const [error, setError] = useState9(null);
971
+ const [selectedId, setSelectedId] = useState9(
825
972
  props.initialPageId ?? props.initialData?.pages[0]?.id ?? ""
826
973
  );
827
974
  useEffect5(() => {
@@ -846,18 +993,18 @@ function MemberContentArea(props) {
846
993
  }
847
994
  return [...result.entries()];
848
995
  }, [data]);
849
- if (error) return /* @__PURE__ */ jsxs10("p", { className: "meeting-note", role: "alert", children: [
996
+ if (error) return /* @__PURE__ */ jsxs11("p", { className: "meeting-note", role: "alert", children: [
850
997
  "Member pages could not be loaded: ",
851
998
  error
852
999
  ] });
853
- if (!data) return /* @__PURE__ */ jsx10(Fragment4, { children: loadingContent });
854
- if (data.pages.length === 0) return /* @__PURE__ */ jsx10(Fragment4, { children: emptyContent });
1000
+ if (!data) return /* @__PURE__ */ jsx11(Fragment5, { children: loadingContent });
1001
+ if (data.pages.length === 0) return /* @__PURE__ */ jsx11(Fragment5, { children: emptyContent });
855
1002
  const selected = data.pages.find((page) => page.id === selectedId) ?? data.pages[0];
856
1003
  const href = selected.upsell && upsellHref ? upsellHref(selected.upsell.tierId, selected) : void 0;
857
- return /* @__PURE__ */ jsxs10("div", { className: "chapter-member-content", "data-member-content": true, children: [
858
- /* @__PURE__ */ jsx10("nav", { className: "chapter-member-content-nav", "aria-label": "Member pages", children: sections.map(([section, pages]) => /* @__PURE__ */ jsxs10("section", { className: "chapter-member-content-section", children: [
859
- /* @__PURE__ */ jsx10("h2", { children: section }),
860
- /* @__PURE__ */ jsx10("ul", { children: pages.map((page) => /* @__PURE__ */ jsx10("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx10(
1004
+ return /* @__PURE__ */ jsxs11("div", { className: "chapter-member-content", "data-member-content": true, children: [
1005
+ /* @__PURE__ */ jsx11("nav", { className: "chapter-member-content-nav", "aria-label": "Member pages", children: sections.map(([section, pages]) => /* @__PURE__ */ jsxs11("section", { className: "chapter-member-content-section", children: [
1006
+ /* @__PURE__ */ jsx11("h2", { children: section }),
1007
+ /* @__PURE__ */ jsx11("ul", { children: pages.map((page) => /* @__PURE__ */ jsx11("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx11(
861
1008
  "button",
862
1009
  {
863
1010
  type: "button",
@@ -867,23 +1014,23 @@ function MemberContentArea(props) {
867
1014
  }
868
1015
  ) }, page.id)) })
869
1016
  ] }, section)) }),
870
- /* @__PURE__ */ jsxs10("article", { className: "chapter-member-content-page", "data-access": selected.access, children: [
871
- /* @__PURE__ */ jsxs10("header", { children: [
872
- /* @__PURE__ */ jsxs10("div", { className: "card-label", children: [
1017
+ /* @__PURE__ */ jsxs11("article", { className: "chapter-member-content-page", "data-access": selected.access, children: [
1018
+ /* @__PURE__ */ jsxs11("header", { children: [
1019
+ /* @__PURE__ */ jsxs11("div", { className: "card-label", children: [
873
1020
  selected.source.type === "parent" ? "Parent" : "Chapter",
874
1021
  " \xB7 ",
875
1022
  selected.access
876
1023
  ] }),
877
- /* @__PURE__ */ jsx10("h1", { children: selected.title }),
878
- selected.summary ? /* @__PURE__ */ jsx10("p", { children: selected.summary }) : null
1024
+ /* @__PURE__ */ jsx11("h1", { children: selected.title }),
1025
+ selected.summary ? /* @__PURE__ */ jsx11("p", { children: selected.summary }) : null
879
1026
  ] }),
880
- selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx10(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs10("div", { className: "chapter-member-content-locked", children: [
881
- selected.teaserMarkdown ? /* @__PURE__ */ jsx10(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx10("p", { children: "This page is not included in your current membership." }),
882
- selected.upsell ? /* @__PURE__ */ jsxs10("aside", { className: "chapter-member-content-upsell", "aria-label": selected.upsell.label ?? "Membership option", children: [
883
- /* @__PURE__ */ jsx10("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
884
- /* @__PURE__ */ jsx10("p", { children: fmtMoney(selected.upsell.priceCents) }),
885
- selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx10(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
886
- href ? /* @__PURE__ */ jsx10("a", { className: "btn primary", href, children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : onUpsell ? /* @__PURE__ */ jsx10("button", { className: "btn primary", type: "button", onClick: () => onUpsell(selected.upsell.tierId, selected), children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : null
1027
+ selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx11(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs11("div", { className: "chapter-member-content-locked", children: [
1028
+ selected.teaserMarkdown ? /* @__PURE__ */ jsx11(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx11("p", { children: "This page is not included in your current membership." }),
1029
+ selected.upsell ? /* @__PURE__ */ jsxs11("aside", { className: "chapter-member-content-upsell", "aria-label": selected.upsell.label ?? "Membership option", children: [
1030
+ /* @__PURE__ */ jsx11("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
1031
+ /* @__PURE__ */ jsx11("p", { children: fmtMoney(selected.upsell.priceCents) }),
1032
+ selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx11(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
1033
+ href ? /* @__PURE__ */ jsx11("a", { className: "btn primary", href, children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : onUpsell ? /* @__PURE__ */ jsx11("button", { className: "btn primary", type: "button", onClick: () => onUpsell(selected.upsell.tierId, selected), children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : null
887
1034
  ] }) : null
888
1035
  ] })
889
1036
  ] })
@@ -891,12 +1038,12 @@ function MemberContentArea(props) {
891
1038
  }
892
1039
 
893
1040
  // src/ui/members.tsx
894
- import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs11 } from "preact/jsx-runtime";
1041
+ import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs12 } from "preact/jsx-runtime";
895
1042
  function card(copy, kicker, body) {
896
- return /* @__PURE__ */ jsxs11("div", { className: "card", children: [
897
- /* @__PURE__ */ jsx11("div", { className: "card-label", children: copy.provisional.cardLabel }),
898
- /* @__PURE__ */ jsxs11("div", { className: "meeting-block", children: [
899
- /* @__PURE__ */ jsx11("div", { className: "meeting-kicker", children: kicker }),
1043
+ return /* @__PURE__ */ jsxs12("div", { className: "card", children: [
1044
+ /* @__PURE__ */ jsx12("div", { className: "card-label", children: copy.provisional.cardLabel }),
1045
+ /* @__PURE__ */ jsxs12("div", { className: "meeting-block", children: [
1046
+ /* @__PURE__ */ jsx12("div", { className: "meeting-kicker", children: kicker }),
900
1047
  body
901
1048
  ] })
902
1049
  ] });
@@ -907,9 +1054,9 @@ function ProvisionalCard(props) {
907
1054
  return card(
908
1055
  copy,
909
1056
  copy.provisional.applicationNeeded,
910
- /* @__PURE__ */ jsxs11(Fragment5, { children: [
911
- /* @__PURE__ */ jsx11("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
912
- /* @__PURE__ */ jsx11("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
1057
+ /* @__PURE__ */ jsxs12(Fragment6, { children: [
1058
+ /* @__PURE__ */ jsx12("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
1059
+ /* @__PURE__ */ jsx12("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
913
1060
  ] })
914
1061
  );
915
1062
  }
@@ -917,19 +1064,19 @@ function ProvisionalCard(props) {
917
1064
  return card(
918
1065
  copy,
919
1066
  copy.provisional.refunded,
920
- /* @__PURE__ */ jsx11("div", { className: "meeting-note", children: copy.provisional.refundedBody })
1067
+ /* @__PURE__ */ jsx12("div", { className: "meeting-note", children: copy.provisional.refundedBody })
921
1068
  );
922
1069
  }
923
- const membership = application.paid ? /* @__PURE__ */ jsx11("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
1070
+ const membership = application.paid ? /* @__PURE__ */ jsx12("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
924
1071
  if (application.meetingAt) {
925
1072
  return card(
926
1073
  copy,
927
1074
  copy.provisional.introductionCall,
928
- /* @__PURE__ */ jsxs11(Fragment5, { children: [
929
- /* @__PURE__ */ jsx11("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
930
- /* @__PURE__ */ jsx11("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
931
- application.meetUrl ? /* @__PURE__ */ jsx11("div", { className: "meeting-note", children: /* @__PURE__ */ jsx11("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
932
- /* @__PURE__ */ jsx11(
1075
+ /* @__PURE__ */ jsxs12(Fragment6, { children: [
1076
+ /* @__PURE__ */ jsx12("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
1077
+ /* @__PURE__ */ jsx12("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
1078
+ application.meetUrl ? /* @__PURE__ */ jsx12("div", { className: "meeting-note", children: /* @__PURE__ */ jsx12("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
1079
+ /* @__PURE__ */ jsx12(
933
1080
  Rescheduler,
934
1081
  {
935
1082
  api,
@@ -946,9 +1093,9 @@ function ProvisionalCard(props) {
946
1093
  return card(
947
1094
  copy,
948
1095
  copy.provisional.bookCall,
949
- /* @__PURE__ */ jsxs11(Fragment5, { children: [
950
- /* @__PURE__ */ jsx11("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
951
- /* @__PURE__ */ jsx11(
1096
+ /* @__PURE__ */ jsxs12(Fragment6, { children: [
1097
+ /* @__PURE__ */ jsx12("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
1098
+ /* @__PURE__ */ jsx12(
952
1099
  Rescheduler,
953
1100
  {
954
1101
  api,
@@ -975,8 +1122,8 @@ function MembersArea(props) {
975
1122
  renderProvisional
976
1123
  } = props;
977
1124
  const copy = props.copy ?? inheritedCopy.members;
978
- const [me, setMe] = useState9(null);
979
- const [error, setError] = useState9(false);
1125
+ const [me, setMe] = useState10(null);
1126
+ const [error, setError] = useState10(false);
980
1127
  const reload = async () => {
981
1128
  try {
982
1129
  setMe(await api("/api/me"));
@@ -987,22 +1134,22 @@ function MembersArea(props) {
987
1134
  useEffect6(() => {
988
1135
  void reload();
989
1136
  }, []);
990
- if (error) return /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: copy.loadFailed });
991
- if (!me) return /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: inheritedCopy.common.loading });
1137
+ if (error) return /* @__PURE__ */ jsx12("p", { className: "meeting-note", children: copy.loadFailed });
1138
+ if (!me) return /* @__PURE__ */ jsx12("p", { className: "meeting-note", children: inheritedCopy.common.loading });
992
1139
  const role = me.role || "provisional";
993
- return /* @__PURE__ */ jsxs11(Fragment5, { children: [
994
- /* @__PURE__ */ jsxs11("div", { className: "card", children: [
995
- /* @__PURE__ */ jsxs11("div", { className: "member-row", children: [
996
- /* @__PURE__ */ jsx11("span", { className: "member-email", children: me.email }),
997
- /* @__PURE__ */ jsx11("span", { className: "role-badge " + role, children: role })
1140
+ return /* @__PURE__ */ jsxs12(Fragment6, { children: [
1141
+ /* @__PURE__ */ jsxs12("div", { className: "card", children: [
1142
+ /* @__PURE__ */ jsxs12("div", { className: "member-row", children: [
1143
+ /* @__PURE__ */ jsx12("span", { className: "member-email", children: me.email }),
1144
+ /* @__PURE__ */ jsx12("span", { className: "role-badge " + role, children: role })
998
1145
  ] }),
999
- /* @__PURE__ */ jsxs11("div", { className: "account-actions", children: [
1000
- /* @__PURE__ */ jsx11("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
1001
- me.authorized || me.superAdmin ? /* @__PURE__ */ jsx11("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
1146
+ /* @__PURE__ */ jsxs12("div", { className: "account-actions", children: [
1147
+ /* @__PURE__ */ jsx12("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
1148
+ me.authorized || me.superAdmin ? /* @__PURE__ */ jsx12("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
1002
1149
  ] })
1003
1150
  ] }),
1004
- me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */ jsx11(MemberRestart, { api, application: me.application, applicationId: me.membershipRestart.applicationId, onComplete: reload }) : me.memberAccess !== true ? (() => {
1005
- const defaultContent = /* @__PURE__ */ jsx11(
1151
+ me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */ jsx12(MemberRestart, { api, application: me.application, applicationId: me.membershipRestart.applicationId, onComplete: reload }) : me.memberAccess !== true ? (() => {
1152
+ const defaultContent = /* @__PURE__ */ jsx12(
1006
1153
  ProvisionalCard,
1007
1154
  {
1008
1155
  api,
@@ -1019,30 +1166,30 @@ function MembersArea(props) {
1019
1166
  reload,
1020
1167
  defaultContent
1021
1168
  }) ?? defaultContent;
1022
- })() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx11(
1169
+ })() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx12(
1023
1170
  MemberContentArea,
1024
1171
  {
1025
1172
  api,
1026
1173
  ...memberPages === true ? {} : memberPages
1027
1174
  }
1028
- ) : /* @__PURE__ */ jsx11("div", { className: "card", children: /* @__PURE__ */ jsx11("div", { className: "card-label", children: copy.full.welcome }) })),
1029
- /* @__PURE__ */ jsx11(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment }),
1030
- me.namedSeatsEnabled ? /* @__PURE__ */ jsx11(NamedSeatPurchase, { api }) : null
1175
+ ) : /* @__PURE__ */ jsx12("div", { className: "card", children: /* @__PURE__ */ jsx12("div", { className: "card-label", children: copy.full.welcome }) })),
1176
+ /* @__PURE__ */ jsx12(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment }),
1177
+ me.namedSeatsEnabled ? /* @__PURE__ */ jsx12(NamedSeatPurchase, { api }) : null
1031
1178
  ] });
1032
1179
  }
1033
1180
 
1034
1181
  // src/ui/join.tsx
1035
- import { useEffect as useEffect10, useRef as useRef3, useState as useState16 } from "preact/hooks";
1182
+ import { useEffect as useEffect10, useRef as useRef3, useState as useState17 } from "preact/hooks";
1036
1183
 
1037
1184
  // src/ui/join-booking.tsx
1038
- import { useEffect as useEffect7, useState as useState10 } from "preact/hooks";
1039
- import { jsx as jsx12, jsxs as jsxs12 } from "preact/jsx-runtime";
1185
+ import { useEffect as useEffect7, useState as useState11 } from "preact/hooks";
1186
+ import { jsx as jsx13, jsxs as jsxs13 } from "preact/jsx-runtime";
1040
1187
  function JoinBooking(props) {
1041
1188
  const { applicationId, copy, onBooked, simulation } = props;
1042
- const [state, setState] = useState10(null);
1043
- const [msg, setMsg] = useState10(null);
1044
- const [busy, setBusy] = useState10(false);
1045
- const [selected, setSelected] = useState10(null);
1189
+ const [state, setState] = useState11(null);
1190
+ const [msg, setMsg] = useState11(null);
1191
+ const [busy, setBusy] = useState11(false);
1192
+ const [selected, setSelected] = useState11(null);
1046
1193
  const load = async () => {
1047
1194
  setMsg(null);
1048
1195
  try {
@@ -1099,11 +1246,11 @@ function JoinBooking(props) {
1099
1246
  setBusy(false);
1100
1247
  }
1101
1248
  };
1102
- if (!state) return /* @__PURE__ */ jsx12("p", { className: "slots-status", children: msg ?? copy.loading });
1103
- return /* @__PURE__ */ jsxs12("div", { className: "join-book", children: [
1104
- /* @__PURE__ */ jsx12("h2", { children: copy.title ?? DEFAULT_JOIN_COPY.booking.title }),
1105
- /* @__PURE__ */ jsx12("p", { children: copy.intro ?? DEFAULT_JOIN_COPY.booking.intro }),
1106
- /* @__PURE__ */ jsx12(
1249
+ if (!state) return /* @__PURE__ */ jsx13("p", { className: "slots-status", children: msg ?? copy.loading });
1250
+ return /* @__PURE__ */ jsxs13("div", { className: "join-book", children: [
1251
+ /* @__PURE__ */ jsx13("h2", { children: copy.title ?? DEFAULT_JOIN_COPY.booking.title }),
1252
+ /* @__PURE__ */ jsx13("p", { children: copy.intro ?? DEFAULT_JOIN_COPY.booking.intro }),
1253
+ /* @__PURE__ */ jsx13(
1107
1254
  SlotPicker,
1108
1255
  {
1109
1256
  slots: state.slots,
@@ -1113,29 +1260,29 @@ function JoinBooking(props) {
1113
1260
  onDayChange: () => setSelected(null)
1114
1261
  }
1115
1262
  ),
1116
- /* @__PURE__ */ jsxs12("div", { className: "slot-confirm", hidden: !selected, children: [
1117
- /* @__PURE__ */ jsx12("button", { className: "submit-btn", disabled: busy, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
1118
- msg ? /* @__PURE__ */ jsx12("p", { className: "step2-note", children: msg }) : null
1263
+ /* @__PURE__ */ jsxs13("div", { className: "slot-confirm", hidden: !selected, children: [
1264
+ /* @__PURE__ */ jsx13("button", { className: "submit-btn", disabled: busy, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
1265
+ msg ? /* @__PURE__ */ jsx13("p", { className: "step2-note", children: msg }) : null
1119
1266
  ] })
1120
1267
  ] });
1121
1268
  }
1122
1269
 
1123
1270
  // src/ui/join-accepted.tsx
1124
- import { jsx as jsx13, jsxs as jsxs13 } from "preact/jsx-runtime";
1271
+ import { jsx as jsx14, jsxs as jsxs14 } from "preact/jsx-runtime";
1125
1272
  function JoinAccepted(props) {
1126
- return /* @__PURE__ */ jsxs13("div", { className: "join-done card", children: [
1127
- /* @__PURE__ */ jsx13("div", { className: "card-label", children: props.copy.accepted.label }),
1128
- /* @__PURE__ */ jsx13("p", { className: "meeting-note", children: props.copy.accepted.body }),
1129
- /* @__PURE__ */ jsx13("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
1273
+ return /* @__PURE__ */ jsxs14("div", { className: "join-done card", children: [
1274
+ /* @__PURE__ */ jsx14("div", { className: "card-label", children: props.copy.accepted.label }),
1275
+ /* @__PURE__ */ jsx14("p", { className: "meeting-note", children: props.copy.accepted.body }),
1276
+ /* @__PURE__ */ jsx14("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
1130
1277
  ] });
1131
1278
  }
1132
1279
 
1133
1280
  // src/ui/gift-claim-card.tsx
1134
- import { useState as useState11 } from "preact/hooks";
1135
- import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs14 } from "preact/jsx-runtime";
1281
+ import { useState as useState12 } from "preact/hooks";
1282
+ import { Fragment as Fragment7, jsx as jsx15, jsxs as jsxs15 } from "preact/jsx-runtime";
1136
1283
  function GiftClaimCard(props) {
1137
- const [code, setCode] = useState11(props.initialCode ?? "");
1138
- const [error, setError] = useState11(false);
1284
+ const [code, setCode] = useState12(props.initialCode ?? "");
1285
+ const [error, setError] = useState12(false);
1139
1286
  const rotate = async () => {
1140
1287
  if (!props.claimId) return;
1141
1288
  setError(false);
@@ -1148,24 +1295,24 @@ function GiftClaimCard(props) {
1148
1295
  if (response.ok && body.code) setCode(body.code);
1149
1296
  else setError(true);
1150
1297
  };
1151
- return /* @__PURE__ */ jsxs14("div", { className: "join-done card", children: [
1152
- /* @__PURE__ */ jsx14("div", { className: "card-label", children: props.copy.label }),
1153
- /* @__PURE__ */ jsx14("p", { className: "meeting-note", children: props.copy.body }),
1154
- code ? /* @__PURE__ */ jsxs14(Fragment6, { children: [
1155
- /* @__PURE__ */ jsx14("output", { className: "gift-code", children: code }),
1156
- /* @__PURE__ */ jsx14("p", { children: props.copy.save })
1298
+ return /* @__PURE__ */ jsxs15("div", { className: "join-done card", children: [
1299
+ /* @__PURE__ */ jsx15("div", { className: "card-label", children: props.copy.label }),
1300
+ /* @__PURE__ */ jsx15("p", { className: "meeting-note", children: props.copy.body }),
1301
+ code ? /* @__PURE__ */ jsxs15(Fragment7, { children: [
1302
+ /* @__PURE__ */ jsx15("output", { className: "gift-code", children: code }),
1303
+ /* @__PURE__ */ jsx15("p", { children: props.copy.save })
1157
1304
  ] }) : null,
1158
- !code && props.claimId ? /* @__PURE__ */ jsx14("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
1159
- error ? /* @__PURE__ */ jsx14("p", { role: "alert", children: props.copy.rotateFailed }) : null
1305
+ !code && props.claimId ? /* @__PURE__ */ jsx15("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
1306
+ error ? /* @__PURE__ */ jsx15("p", { role: "alert", children: props.copy.rotateFailed }) : null
1160
1307
  ] });
1161
1308
  }
1162
1309
 
1163
1310
  // src/ui/join-tiers.tsx
1164
- import { useState as useState12 } from "preact/hooks";
1165
- import { Fragment as Fragment7, jsx as jsx15, jsxs as jsxs15 } from "preact/jsx-runtime";
1311
+ import { useState as useState13 } from "preact/hooks";
1312
+ import { Fragment as Fragment8, jsx as jsx16, jsxs as jsxs16 } from "preact/jsx-runtime";
1166
1313
  var joinTierMoney = (cents, currency = "usd") => new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
1167
1314
  function useTierSelection(tiers, initialTierId) {
1168
- const [selectedTierId, setSelectedTierId] = useState12(() => {
1315
+ const [selectedTierId, setSelectedTierId] = useState13(() => {
1169
1316
  const preset = tiers.find((tier) => tier.id === initialTierId);
1170
1317
  if (preset) return preset.id;
1171
1318
  return tiers.length === 1 ? tiers[0].id : null;
@@ -1180,10 +1327,10 @@ function useTierSelection(tiers, initialTierId) {
1180
1327
  };
1181
1328
  }
1182
1329
  function TierPlaceholder(context) {
1183
- return /* @__PURE__ */ jsxs15("fieldset", { "data-chapter-placeholder": "tiers", children: [
1184
- /* @__PURE__ */ jsx15("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
1185
- context.tiers.map((tier) => /* @__PURE__ */ jsxs15("label", { children: [
1186
- /* @__PURE__ */ jsx15(
1330
+ return /* @__PURE__ */ jsxs16("fieldset", { "data-chapter-placeholder": "tiers", children: [
1331
+ /* @__PURE__ */ jsx16("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
1332
+ context.tiers.map((tier) => /* @__PURE__ */ jsxs16("label", { children: [
1333
+ /* @__PURE__ */ jsx16(
1187
1334
  "input",
1188
1335
  {
1189
1336
  type: "radio",
@@ -1194,13 +1341,13 @@ function TierPlaceholder(context) {
1194
1341
  }
1195
1342
  ),
1196
1343
  tier.name,
1197
- tier.founding ? /* @__PURE__ */ jsxs15(Fragment7, { children: [
1344
+ tier.founding ? /* @__PURE__ */ jsxs16(Fragment8, { children: [
1198
1345
  " \u2014 ",
1199
1346
  joinTierMoney(tier.founding.dueTodayCents),
1200
1347
  " founding member rate (list ",
1201
1348
  joinTierMoney(tier.priceCents),
1202
1349
  ")"
1203
- ] }) : tier.free ? " \u2014 free" : /* @__PURE__ */ jsxs15(Fragment7, { children: [
1350
+ ] }) : tier.free ? " \u2014 free" : /* @__PURE__ */ jsxs16(Fragment8, { children: [
1204
1351
  " \u2014 ",
1205
1352
  joinTierMoney(tier.priceCents)
1206
1353
  ] })
@@ -1212,19 +1359,19 @@ function tierNeedsPayment(selected, paymentsReady) {
1212
1359
  }
1213
1360
 
1214
1361
  // src/ui/join-application-form.tsx
1215
- import { jsx as jsx16, jsxs as jsxs16 } from "preact/jsx-runtime";
1362
+ import { jsx as jsx17, jsxs as jsxs17 } from "preact/jsx-runtime";
1216
1363
  function JoinApplicationForm({ props, copy, invitation, requestedSeat, tierSelection, giftOfferId, selectGift, submitting, error, submit }) {
1217
1364
  const disabled = submitting || props.submitDisabled === true;
1218
- return /* @__PURE__ */ jsxs16("form", { className: "join-form", onSubmit: (event) => void submit(event), children: [
1219
- !requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs16("fieldset", { children: [
1220
- /* @__PURE__ */ jsx16("legend", { children: copy.gift.optionsLabel }),
1221
- /* @__PURE__ */ jsx16("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => selectGift(null), children: copy.gift.chooseSelf }),
1222
- /* @__PURE__ */ jsx16(GiftOfferCards, { offers: props.config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: selectGift })
1365
+ return /* @__PURE__ */ jsxs17("form", { className: "join-form", onSubmit: (event) => void submit(event), children: [
1366
+ !requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs17("fieldset", { children: [
1367
+ /* @__PURE__ */ jsx17("legend", { children: copy.gift.optionsLabel }),
1368
+ /* @__PURE__ */ jsx17("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => selectGift(null), children: copy.gift.chooseSelf }),
1369
+ /* @__PURE__ */ jsx17(GiftOfferCards, { offers: props.config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: selectGift })
1223
1370
  ] }) : null,
1224
1371
  !requestedSeat && (props.config.tiers?.length ?? 0) > 1 ? props.renderTiers?.(tierSelection) ?? TierPlaceholder(tierSelection) : null,
1225
1372
  typeof props.children === "function" ? props.children({ invitation }) : props.children,
1226
- error ? /* @__PURE__ */ jsx16("p", { className: "join-error", role: "alert", children: error }) : null,
1227
- props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */ jsx16("button", { className: "submit-btn", type: "submit", disabled, children: submitting ? copy.form.submitting : copy.form.submit })
1373
+ error ? /* @__PURE__ */ jsx17("p", { className: "join-error", role: "alert", children: error }) : null,
1374
+ props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */ jsx17("button", { className: "submit-btn", type: "submit", disabled, children: submitting ? copy.form.submitting : copy.form.submit })
1228
1375
  ] });
1229
1376
  }
1230
1377
 
@@ -1249,8 +1396,8 @@ function joinStateFromApplicationResponse(data, fallbackNeedsPayment, submittedG
1249
1396
 
1250
1397
  // src/ui/gift-code-redeemer.tsx
1251
1398
  import { InlineActionField } from "@odla-ai/ui/components";
1252
- import { useState as useState13 } from "preact/hooks";
1253
- import { Fragment as Fragment8, jsx as jsx17, jsxs as jsxs17 } from "preact/jsx-runtime";
1399
+ import { useState as useState14 } from "preact/hooks";
1400
+ import { Fragment as Fragment9, jsx as jsx18, jsxs as jsxs18 } from "preact/jsx-runtime";
1254
1401
  var GIFT_CODE_REDEEMER_CSS = `
1255
1402
  .gift-code-redeemer{container-type:inline-size;display:grid;gap:var(--ui-space-1,.35rem);margin:0}
1256
1403
  .gift-code-redeemer .inline-action-field-label{display:block;color:var(--ui-text-muted,#66777f);font-size:var(--ui-text-xs,.72rem);font-weight:var(--ui-weight-strong,700);letter-spacing:var(--ui-tracking-caps,.08em);text-transform:uppercase}
@@ -1265,10 +1412,10 @@ var GIFT_CODE_REDEEMER_CSS = `
1265
1412
  @container (max-width:26rem){.gift-code-redeemer .inline-action-field-row{grid-template-columns:minmax(0,1fr)}.gift-code-redeemer .inline-action-field-action{width:100%}}
1266
1413
  `;
1267
1414
  function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
1268
- const [code, setCode] = useState13("");
1269
- const [loading, setLoading] = useState13(false);
1270
- const [message, setMessage] = useState13("");
1271
- const [messageTone, setMessageTone] = useState13("neutral");
1415
+ const [code, setCode] = useState14("");
1416
+ const [loading, setLoading] = useState14(false);
1417
+ const [message, setMessage] = useState14("");
1418
+ const [messageTone, setMessageTone] = useState14("neutral");
1272
1419
  const normalizedCode = code.trim();
1273
1420
  const redeem = async () => {
1274
1421
  if (!normalizedCode || loading) return;
@@ -1295,9 +1442,9 @@ function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
1295
1442
  setLoading(false);
1296
1443
  }
1297
1444
  };
1298
- return /* @__PURE__ */ jsxs17(Fragment8, { children: [
1299
- /* @__PURE__ */ jsx17("style", { children: GIFT_CODE_REDEEMER_CSS }),
1300
- /* @__PURE__ */ jsx17(
1445
+ return /* @__PURE__ */ jsxs18(Fragment9, { children: [
1446
+ /* @__PURE__ */ jsx18("style", { children: GIFT_CODE_REDEEMER_CSS }),
1447
+ /* @__PURE__ */ jsx18(
1301
1448
  InlineActionField,
1302
1449
  {
1303
1450
  id,
@@ -1353,12 +1500,12 @@ async function loadJoinResume(applicationId, fetcher = fetch) {
1353
1500
  }
1354
1501
 
1355
1502
  // src/ui/join-gift-claim.tsx
1356
- import { jsx as jsx18, jsxs as jsxs18 } from "preact/jsx-runtime";
1503
+ import { jsx as jsx19, jsxs as jsxs19 } from "preact/jsx-runtime";
1357
1504
  function JoinGiftClaim(props) {
1358
- return /* @__PURE__ */ jsxs18("section", { className: "join-gift-claim card", children: [
1359
- /* @__PURE__ */ jsx18("div", { className: "card-label", children: props.copy.claimTitle }),
1360
- /* @__PURE__ */ jsx18("p", { children: props.copy.claimBody }),
1361
- /* @__PURE__ */ jsx18(
1505
+ return /* @__PURE__ */ jsxs19("section", { className: "join-gift-claim card", children: [
1506
+ /* @__PURE__ */ jsx19("div", { className: "card-label", children: props.copy.claimTitle }),
1507
+ /* @__PURE__ */ jsx19("p", { children: props.copy.claimBody }),
1508
+ /* @__PURE__ */ jsx19(
1362
1509
  GiftCodeRedeemer,
1363
1510
  {
1364
1511
  api: props.api,
@@ -1382,21 +1529,21 @@ function JoinGiftClaim(props) {
1382
1529
  }
1383
1530
 
1384
1531
  // src/ui/join-named-seat.tsx
1385
- import { useState as useState14 } from "preact/hooks";
1386
- import { jsx as jsx19, jsxs as jsxs19 } from "preact/jsx-runtime";
1532
+ import { useState as useState15 } from "preact/hooks";
1533
+ import { jsx as jsx20, jsxs as jsxs20 } from "preact/jsx-runtime";
1387
1534
  function JoinNamedSeat(props) {
1388
1535
  const seatId = props.seatId ?? "";
1389
1536
  const inherited = useChapterCopy(), copy = props.copy ?? inherited.join.namedSeat;
1390
- const [accepted, setAccepted] = useState14(false), [busy, setBusy] = useState14(false), [error, setError] = useState14("");
1391
- return /* @__PURE__ */ jsxs19("section", { className: "join-named-seat card", children: [
1392
- /* @__PURE__ */ jsx19("h2", { children: copy.title }),
1393
- /* @__PURE__ */ jsx19("p", { children: copy.body }),
1394
- /* @__PURE__ */ jsxs19("label", { className: "journey-consent", children: [
1395
- /* @__PURE__ */ jsx19("input", { type: "checkbox", checked: accepted, disabled: busy, onChange: (event) => setAccepted(event.currentTarget.checked) }),
1396
- /* @__PURE__ */ jsx19("span", { children: copy.consent })
1537
+ const [accepted, setAccepted] = useState15(false), [busy, setBusy] = useState15(false), [error, setError] = useState15("");
1538
+ return /* @__PURE__ */ jsxs20("section", { className: "join-named-seat card", children: [
1539
+ /* @__PURE__ */ jsx20("h2", { children: copy.title }),
1540
+ /* @__PURE__ */ jsx20("p", { children: copy.body }),
1541
+ /* @__PURE__ */ jsxs20("label", { className: "journey-consent", children: [
1542
+ /* @__PURE__ */ jsx20("input", { type: "checkbox", checked: accepted, disabled: busy, onChange: (event) => setAccepted(event.currentTarget.checked) }),
1543
+ /* @__PURE__ */ jsx20("span", { children: copy.consent })
1397
1544
  ] }),
1398
- error ? /* @__PURE__ */ jsx19("p", { role: "alert", children: error }) : null,
1399
- /* @__PURE__ */ jsx19("button", { type: "button", className: "btn btn-primary", disabled: busy || !accepted || !seatId.trim(), onClick: async () => {
1545
+ error ? /* @__PURE__ */ jsx20("p", { role: "alert", children: error }) : null,
1546
+ /* @__PURE__ */ jsx20("button", { type: "button", className: "btn btn-primary", disabled: busy || !accepted || !seatId.trim(), onClick: async () => {
1400
1547
  setBusy(true);
1401
1548
  setError("");
1402
1549
  try {
@@ -1416,12 +1563,12 @@ function JoinNamedSeat(props) {
1416
1563
  }
1417
1564
 
1418
1565
  // src/ui/join-invitation.tsx
1419
- import { useEffect as useEffect8, useState as useState15 } from "preact/hooks";
1420
- import { jsx as jsx20, jsxs as jsxs20 } from "preact/jsx-runtime";
1566
+ import { useEffect as useEffect8, useState as useState16 } from "preact/hooks";
1567
+ import { jsx as jsx21, jsxs as jsxs21 } from "preact/jsx-runtime";
1421
1568
  function useJoinInvitation(seatId, api, fallback) {
1422
- const [invitation, setInvitation] = useState15(null);
1423
- const [error, setError] = useState15("");
1424
- const [revision, setRevision] = useState15(0);
1569
+ const [invitation, setInvitation] = useState16(null);
1570
+ const [error, setError] = useState16("");
1571
+ const [revision, setRevision] = useState16(0);
1425
1572
  useEffect8(() => {
1426
1573
  let live = true;
1427
1574
  setInvitation(null);
@@ -1444,9 +1591,9 @@ function useJoinInvitation(seatId, api, fallback) {
1444
1591
  return { invitation: invitation?.seatId === seatId ? invitation : null, error, retry: () => setRevision((value) => value + 1) };
1445
1592
  }
1446
1593
  function JoinInvitationNotice(props) {
1447
- return /* @__PURE__ */ jsxs20("aside", { className: "journey-invitation", "aria-label": props.copy.title, children: [
1448
- /* @__PURE__ */ jsx20("p", { children: /* @__PURE__ */ jsx20("strong", { children: formatChapterCopy(props.copy.from, { purchaserName: props.invitation.purchaserName }) }) }),
1449
- /* @__PURE__ */ jsx20("p", { children: formatChapterCopy(props.copy.prepaid, { tierName: props.tierName }) })
1594
+ return /* @__PURE__ */ jsxs21("aside", { className: "journey-invitation", "aria-label": props.copy.title, children: [
1595
+ /* @__PURE__ */ jsx21("p", { children: /* @__PURE__ */ jsx21("strong", { children: formatChapterCopy(props.copy.from, { purchaserName: props.invitation.purchaserName }) }) }),
1596
+ /* @__PURE__ */ jsx21("p", { children: formatChapterCopy(props.copy.prepaid, { tierName: props.tierName }) })
1450
1597
  ] });
1451
1598
  }
1452
1599
 
@@ -1476,9 +1623,9 @@ function useJoinPending(state, loadResume, setState) {
1476
1623
  }
1477
1624
 
1478
1625
  // src/ui/join.tsx
1479
- import { Fragment as Fragment9, jsx as jsx21, jsxs as jsxs21 } from "preact/jsx-runtime";
1626
+ import { Fragment as Fragment10, jsx as jsx22, jsxs as jsxs22 } from "preact/jsx-runtime";
1480
1627
  function JoinIsland(props) {
1481
- return /* @__PURE__ */ jsx21(JourneyFrame, { children: /* @__PURE__ */ jsx21(JoinFlow, { ...props }) });
1628
+ return /* @__PURE__ */ jsx22(JourneyFrame, { children: /* @__PURE__ */ jsx22(JoinFlow, { ...props }) });
1482
1629
  }
1483
1630
  function JoinFlow(props) {
1484
1631
  const inheritedCopy = useChapterCopy();
@@ -1499,10 +1646,10 @@ function JoinFlow(props) {
1499
1646
  const invitation = invitationState.invitation;
1500
1647
  const selectedTierId = invitation?.skuId ?? tierSelection.selectedTierId;
1501
1648
  const selectedTier = tiers.find((tier) => tier.id === selectedTierId) ?? tierSelection.selected;
1502
- const [state, setState] = useState16(requestedSeat ? { step: "form" } : props.initialState ?? { step: "form" });
1503
- const [error, setError] = useState16(null);
1504
- const [submitting, setSubmitting] = useState16(false);
1505
- const [giftOfferId, setGiftOfferId] = useState16(props.initialGiftOfferId ?? null);
1649
+ const [state, setState] = useState17(requestedSeat ? { step: "form" } : props.initialState ?? { step: "form" });
1650
+ const [error, setError] = useState17(null);
1651
+ const [submitting, setSubmitting] = useState17(false);
1652
+ const [giftOfferId, setGiftOfferId] = useState17(props.initialGiftOfferId ?? null);
1506
1653
  const simulatedPayment = props.simulation ? props.simulation.payment ?? {
1507
1654
  lineItems: {
1508
1655
  standardCents: selectedTier?.priceCents ?? 0,
@@ -1581,13 +1728,13 @@ function JoinFlow(props) {
1581
1728
  setSubmitting(false);
1582
1729
  }
1583
1730
  };
1584
- if (requestedSeat && !invitation) return /* @__PURE__ */ jsxs21("section", { className: "card", "aria-live": "polite", children: [
1585
- /* @__PURE__ */ jsx21("h2", { children: seatCopy.title }),
1586
- /* @__PURE__ */ jsx21("p", { role: invitationState.error ? "alert" : "status", children: invitationState.error || seatCopy.loading }),
1587
- invitationState.error ? /* @__PURE__ */ jsx21("button", { type: "button", onClick: invitationState.retry, children: seatCopy.retry }) : null
1731
+ if (requestedSeat && !invitation) return /* @__PURE__ */ jsxs22("section", { className: "card", "aria-live": "polite", children: [
1732
+ /* @__PURE__ */ jsx22("h2", { children: seatCopy.title }),
1733
+ /* @__PURE__ */ jsx22("p", { role: invitationState.error ? "alert" : "status", children: invitationState.error || seatCopy.loading }),
1734
+ invitationState.error ? /* @__PURE__ */ jsx22("button", { type: "button", onClick: invitationState.retry, children: seatCopy.retry }) : null
1588
1735
  ] });
1589
- const header = /* @__PURE__ */ jsxs21(Fragment9, { children: [
1590
- invitation ? /* @__PURE__ */ jsx21(
1736
+ const header = /* @__PURE__ */ jsxs22(Fragment10, { children: [
1737
+ invitation ? /* @__PURE__ */ jsx22(
1591
1738
  JoinInvitationNotice,
1592
1739
  {
1593
1740
  invitation,
@@ -1602,45 +1749,45 @@ function JoinFlow(props) {
1602
1749
  })
1603
1750
  ] });
1604
1751
  if (state.step === "closed") {
1605
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1752
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1606
1753
  header,
1607
- /* @__PURE__ */ jsxs21("section", { className: "card", "aria-label": "Application closed", children: [
1608
- /* @__PURE__ */ jsx21("h2", { children: "This application is closed" }),
1609
- /* @__PURE__ */ jsx21("p", { children: "This link cannot resume payment or booking. Sign in to view your application status, or contact the chapter if you need help." }),
1610
- /* @__PURE__ */ jsx21("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
1754
+ /* @__PURE__ */ jsxs22("section", { className: "card", "aria-label": "Application closed", children: [
1755
+ /* @__PURE__ */ jsx22("h2", { children: "This application is closed" }),
1756
+ /* @__PURE__ */ jsx22("p", { children: "This link cannot resume payment or booking. Sign in to view your application status, or contact the chapter if you need help." }),
1757
+ /* @__PURE__ */ jsx22("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
1611
1758
  ] })
1612
1759
  ] });
1613
1760
  }
1614
1761
  if (state.step === "done") {
1615
- const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs21("div", { className: "join-done card", children: [
1616
- /* @__PURE__ */ jsx21("div", { className: "card-label", children: copy.done.label }),
1617
- /* @__PURE__ */ jsx21("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
1618
- /* @__PURE__ */ jsx21("p", { className: "meeting-note", children: copy.done.calendarInvite }),
1619
- /* @__PURE__ */ jsx21("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
1762
+ const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs22("div", { className: "join-done card", children: [
1763
+ /* @__PURE__ */ jsx22("div", { className: "card-label", children: copy.done.label }),
1764
+ /* @__PURE__ */ jsx22("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
1765
+ /* @__PURE__ */ jsx22("p", { className: "meeting-note", children: copy.done.calendarInvite }),
1766
+ /* @__PURE__ */ jsx22("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
1620
1767
  ] });
1621
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1768
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1622
1769
  header,
1623
1770
  body
1624
1771
  ] });
1625
1772
  }
1626
1773
  if (state.step === "accepted") {
1627
- const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx21(JoinAccepted, { copy, membersHref });
1628
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1774
+ const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx22(JoinAccepted, { copy, membersHref });
1775
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1629
1776
  header,
1630
1777
  body
1631
1778
  ] });
1632
1779
  }
1633
1780
  if (state.step === "gift") {
1634
- const body = renderGift?.(state) ?? /* @__PURE__ */ jsx21(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
1635
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1781
+ const body = renderGift?.(state) ?? /* @__PURE__ */ jsx22(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
1782
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1636
1783
  header,
1637
1784
  body
1638
1785
  ] });
1639
1786
  }
1640
1787
  if (state.step === "booking") {
1641
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1788
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1642
1789
  header,
1643
- /* @__PURE__ */ jsx21(
1790
+ /* @__PURE__ */ jsx22(
1644
1791
  JoinBooking,
1645
1792
  {
1646
1793
  applicationId: state.applicationId,
@@ -1655,9 +1802,9 @@ function JoinFlow(props) {
1655
1802
  }
1656
1803
  if (state.step === "payment") {
1657
1804
  if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation && !state.giftPurchase) {
1658
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1805
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1659
1806
  header,
1660
- /* @__PURE__ */ jsx21(
1807
+ /* @__PURE__ */ jsx22(
1661
1808
  JoinNamedSeat,
1662
1809
  {
1663
1810
  api: props.namedSeatClaimApi,
@@ -1670,9 +1817,9 @@ function JoinFlow(props) {
1670
1817
  ] });
1671
1818
  }
1672
1819
  const Payment = state.giftPurchase || props.simulation ? PaymentStep : MembershipPaymentStep;
1673
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1820
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1674
1821
  header,
1675
- props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx21(
1822
+ props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx22(
1676
1823
  JoinGiftClaim,
1677
1824
  {
1678
1825
  api: props.giftClaimApi,
@@ -1683,7 +1830,7 @@ function JoinFlow(props) {
1683
1830
  onError: () => setError(copy.form.unexpectedFailure)
1684
1831
  }
1685
1832
  ) : null,
1686
- /* @__PURE__ */ jsx21(
1833
+ /* @__PURE__ */ jsx22(
1687
1834
  Payment,
1688
1835
  {
1689
1836
  applicationId: state.applicationId,
@@ -1691,6 +1838,7 @@ function JoinFlow(props) {
1691
1838
  merchantDisclosureText: config.merchantDisclosureText,
1692
1839
  copy: copy.payment,
1693
1840
  appearance: props.payment?.appearance,
1841
+ initialNamedSeat: props.payment?.initialNamedSeat,
1694
1842
  fonts: props.payment?.fonts,
1695
1843
  renderPriceLines: props.payment?.renderPriceLines,
1696
1844
  simulation: simulatedPayment,
@@ -1712,9 +1860,9 @@ function JoinFlow(props) {
1712
1860
  }
1713
1861
  if (state.step === "paymentPending") {
1714
1862
  if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation) {
1715
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1863
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1716
1864
  header,
1717
- /* @__PURE__ */ jsx21(
1865
+ /* @__PURE__ */ jsx22(
1718
1866
  JoinNamedSeat,
1719
1867
  {
1720
1868
  api: props.namedSeatClaimApi,
@@ -1726,14 +1874,14 @@ function JoinFlow(props) {
1726
1874
  )
1727
1875
  ] });
1728
1876
  }
1729
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1877
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1730
1878
  header,
1731
- /* @__PURE__ */ jsx21("p", { className: "pay-status", role: "status", children: copy.payment.pending })
1879
+ /* @__PURE__ */ jsx22("p", { className: "pay-status", role: "status", children: copy.payment.pending })
1732
1880
  ] });
1733
1881
  }
1734
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
1882
+ return /* @__PURE__ */ jsxs22(Fragment10, { children: [
1735
1883
  header,
1736
- /* @__PURE__ */ jsx21(
1884
+ /* @__PURE__ */ jsx22(
1737
1885
  JoinApplicationForm,
1738
1886
  {
1739
1887
  props,
@@ -1923,7 +2071,7 @@ function membershipPageDocument(input, options = {}) {
1923
2071
  }
1924
2072
 
1925
2073
  // src/ui/membership-cards.tsx
1926
- import { jsx as jsx22, jsxs as jsxs22 } from "preact/jsx-runtime";
2074
+ import { jsx as jsx23, jsxs as jsxs23 } from "preact/jsx-runtime";
1927
2075
  var MEMBERSHIP_CARD_TOKEN_DEFAULTS = Object.freeze({
1928
2076
  "--ui-membership-grid-gap": "1.4rem",
1929
2077
  "--ui-membership-card-padding": "2rem 1.7rem 1.8rem",
@@ -1992,67 +2140,67 @@ function membershipApplicationHref(applicationPath, tierId) {
1992
2140
  }
1993
2141
  function TierAction(props) {
1994
2142
  if (props.mode === "select") {
1995
- return /* @__PURE__ */ jsxs22("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
2143
+ return /* @__PURE__ */ jsxs23("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
1996
2144
  props.label,
1997
- /* @__PURE__ */ jsx22("span", { "aria-hidden": "true", children: "\u2192" })
2145
+ /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", children: "\u2192" })
1998
2146
  ] });
1999
2147
  }
2000
2148
  if (props.mode === "preview") {
2001
- return /* @__PURE__ */ jsxs22("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
2149
+ return /* @__PURE__ */ jsxs23("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
2002
2150
  props.label,
2003
- /* @__PURE__ */ jsx22("span", { "aria-hidden": "true", children: "\u2192" })
2151
+ /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", children: "\u2192" })
2004
2152
  ] });
2005
2153
  }
2006
- return /* @__PURE__ */ jsxs22("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
2154
+ return /* @__PURE__ */ jsxs23("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
2007
2155
  props.label,
2008
- /* @__PURE__ */ jsx22("span", { "aria-hidden": "true", children: "\u2192" })
2156
+ /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", children: "\u2192" })
2009
2157
  ] });
2010
2158
  }
2011
2159
  function TierCard(props) {
2012
2160
  const { tier, presentation } = props;
2013
2161
  const summary = presentation.summaryMarkdown ?? tier.blurb;
2014
2162
  const action = presentation.ctaLabel ?? (tier.free ? "Join for free" : `Choose ${tier.name}`);
2015
- return /* @__PURE__ */ jsxs22("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
2016
- presentation.badge ? /* @__PURE__ */ jsx22("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
2017
- /* @__PURE__ */ jsx22("h3", { className: "chapter-membership-name", children: tier.name }),
2018
- /* @__PURE__ */ jsxs22("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
2019
- presentation.capacity ? /* @__PURE__ */ jsxs22("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
2020
- /* @__PURE__ */ jsx22("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
2021
- /* @__PURE__ */ jsx22("small", { children: presentation.capacity.label ?? "available" })
2163
+ return /* @__PURE__ */ jsxs23("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
2164
+ presentation.badge ? /* @__PURE__ */ jsx23("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
2165
+ /* @__PURE__ */ jsx23("h3", { className: "chapter-membership-name", children: tier.name }),
2166
+ /* @__PURE__ */ jsxs23("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
2167
+ presentation.capacity ? /* @__PURE__ */ jsxs23("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
2168
+ /* @__PURE__ */ jsx23("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
2169
+ /* @__PURE__ */ jsx23("small", { children: presentation.capacity.label ?? "available" })
2022
2170
  ] }) : null,
2023
- /* @__PURE__ */ jsxs22("div", { className: "chapter-membership-price-stack", children: [
2024
- presentation.priceEyebrow ? /* @__PURE__ */ jsx22("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : tier.founding ? /* @__PURE__ */ jsx22("p", { className: "chapter-membership-price-eyebrow", children: "Founding member rate" }) : null,
2025
- /* @__PURE__ */ jsxs22("div", { className: "chapter-membership-price-row", children: [
2026
- tier.founding ? /* @__PURE__ */ jsx22("span", { className: "chapter-membership-compare", children: fmtMoney(tier.priceCents) }) : presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx22("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
2027
- /* @__PURE__ */ jsx22("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.founding ? tier.founding.dueTodayCents : tier.priceCents) }),
2028
- !tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx22("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
2171
+ /* @__PURE__ */ jsxs23("div", { className: "chapter-membership-price-stack", children: [
2172
+ presentation.priceEyebrow ? /* @__PURE__ */ jsx23("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : tier.founding ? /* @__PURE__ */ jsx23("p", { className: "chapter-membership-price-eyebrow", children: "Founding member rate" }) : null,
2173
+ /* @__PURE__ */ jsxs23("div", { className: "chapter-membership-price-row", children: [
2174
+ tier.founding ? /* @__PURE__ */ jsx23("span", { className: "chapter-membership-compare", children: fmtMoney(tier.priceCents) }) : presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx23("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
2175
+ /* @__PURE__ */ jsx23("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.founding ? tier.founding.dueTodayCents : tier.priceCents) }),
2176
+ !tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx23("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
2029
2177
  ] })
2030
2178
  ] })
2031
2179
  ] }),
2032
- presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx22(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
2033
- summary ? /* @__PURE__ */ jsx22(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
2034
- presentation.benefits?.length ? /* @__PURE__ */ jsx22("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs22("li", { children: [
2035
- /* @__PURE__ */ jsx22("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
2036
- /* @__PURE__ */ jsx22(Markdown2, { className: "chapter-membership-benefit", source: benefit })
2180
+ presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx23(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
2181
+ summary ? /* @__PURE__ */ jsx23(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
2182
+ presentation.benefits?.length ? /* @__PURE__ */ jsx23("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs23("li", { children: [
2183
+ /* @__PURE__ */ jsx23("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
2184
+ /* @__PURE__ */ jsx23(Markdown2, { className: "chapter-membership-benefit", source: benefit })
2037
2185
  ] }, `${tier.id}-benefit-${index}`)) }) : null,
2038
- presentation.callout ? /* @__PURE__ */ jsxs22("aside", { className: "chapter-membership-callout", children: [
2039
- presentation.callout.label ? /* @__PURE__ */ jsx22("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
2040
- /* @__PURE__ */ jsx22(Markdown2, { source: presentation.callout.bodyMarkdown })
2186
+ presentation.callout ? /* @__PURE__ */ jsxs23("aside", { className: "chapter-membership-callout", children: [
2187
+ presentation.callout.label ? /* @__PURE__ */ jsx23("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
2188
+ /* @__PURE__ */ jsx23(Markdown2, { source: presentation.callout.bodyMarkdown })
2041
2189
  ] }) : null,
2042
- /* @__PURE__ */ jsx22(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
2190
+ /* @__PURE__ */ jsx23(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
2043
2191
  ] });
2044
2192
  }
2045
2193
  function MembershipCards(props) {
2046
2194
  const document2 = membershipPageDocument(props.document, { tiers: props.tiers });
2047
2195
  const byId = new Map(props.tiers.map((tier) => [tier.id, tier]));
2048
2196
  const mode = props.mode ?? "link";
2049
- return /* @__PURE__ */ jsxs22("section", { className: ["chapter-membership", props.className].filter(Boolean).join(" "), "data-chapter-membership": MEMBERSHIP_PAGE_RENDERER, "aria-label": props.ariaLabel ?? "Membership options", children: [
2050
- /* @__PURE__ */ jsx22("style", { children: MEMBERSHIP_CARDS_CSS }),
2051
- /* @__PURE__ */ jsx22("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
2197
+ return /* @__PURE__ */ jsxs23("section", { className: ["chapter-membership", props.className].filter(Boolean).join(" "), "data-chapter-membership": MEMBERSHIP_PAGE_RENDERER, "aria-label": props.ariaLabel ?? "Membership options", children: [
2198
+ /* @__PURE__ */ jsx23("style", { children: MEMBERSHIP_CARDS_CSS }),
2199
+ /* @__PURE__ */ jsx23("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
2052
2200
  const tier = byId.get(presentation.tierId);
2053
- return /* @__PURE__ */ jsx22(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
2201
+ return /* @__PURE__ */ jsx23(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
2054
2202
  }) }),
2055
- document2.footnoteMarkdown ? /* @__PURE__ */ jsx22(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
2203
+ document2.footnoteMarkdown ? /* @__PURE__ */ jsx23(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
2056
2204
  ] });
2057
2205
  }
2058
2206
 
@@ -2088,4 +2236,4 @@ export {
2088
2236
  membershipApplicationHref,
2089
2237
  MembershipCards
2090
2238
  };
2091
- //# sourceMappingURL=chunk-SPEL4OGE.js.map
2239
+ //# sourceMappingURL=chunk-VEOGTSVX.js.map