@odla-ai/chapter 0.58.0 → 0.59.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.
@@ -2,7 +2,7 @@ import {
2
2
  DEFAULT_JOIN_COPY,
3
3
  formatChapterCopy,
4
4
  useChapterCopy
5
- } from "./chunk-FHKZVF5G.js";
5
+ } from "./chunk-GADLTNJF.js";
6
6
  import {
7
7
  collectFormFields
8
8
  } from "./chunk-IVXVECKR.js";
@@ -72,11 +72,12 @@ var DEFAULT_CLASSES = {
72
72
  time: "slot-time"
73
73
  };
74
74
  function SlotPicker(props) {
75
- const { slots, timezone, selectedStartAt, onPick, onDayChange, classes = DEFAULT_CLASSES } = props;
75
+ const { slots, timezone, selectedStartAt, onPick, onDayChange, classes = DEFAULT_CLASSES, initialDay = "first" } = props;
76
76
  const byDay = useMemo(() => groupSlotsByDay(slots, timezone), [slots, timezone]);
77
77
  const dayKeys = [...byDay.keys()];
78
- const [activeDay, setActiveDay] = useState(dayKeys[0]);
79
- const day2 = activeDay !== void 0 && byDay.has(activeDay) ? activeDay : dayKeys[0];
78
+ const [activeDay, setActiveDay] = useState(initialDay === "first" ? dayKeys[0] : void 0);
79
+ const fallback = initialDay === "first" ? dayKeys[0] : void 0;
80
+ const day2 = activeDay !== void 0 && byDay.has(activeDay) ? activeDay : fallback;
80
81
  const times = (day2 !== void 0 ? byDay.get(day2) : void 0) ?? [];
81
82
  return /* @__PURE__ */ jsxs(Fragment, { children: [
82
83
  /* @__PURE__ */ jsx("div", { className: classes.days, children: dayKeys.map((key) => {
@@ -89,7 +90,7 @@ function SlotPicker(props) {
89
90
  "aria-pressed": key === day2,
90
91
  onClick: () => {
91
92
  setActiveDay(key);
92
- onDayChange?.();
93
+ onDayChange?.(key);
93
94
  },
94
95
  children: first ? dayLabel(first.startAt, timezone) : key
95
96
  },
@@ -785,6 +786,12 @@ var styles = `
785
786
  .chapter-journey fieldset{min-width:0;border:0;padding:0;margin:0}
786
787
  .chapter-journey .checkout-seat-terms{margin-block:1rem}
787
788
  .chapter-journey .checkout-seat-terms summary{cursor:pointer}
789
+ @media(pointer:coarse){.chapter-journey :is(input:not([type=checkbox]):not([type=radio]),select,textarea){font-size:max(1rem,16px)}}
790
+ .chapter-journey .slot-confirm{display:grid;gap:.5rem;margin-block:1rem}
791
+ .chapter-journey .slot-hint{margin:0;color:var(--ui-text-muted,#536360);font-size:.95rem}
792
+ .chapter-journey .member-named-seat-invite{display:grid;gap:.6rem;padding:1rem;margin-block:1rem;background:var(--ui-surface-2,#f3f5f2);border-radius:10px}
793
+ .chapter-journey .member-named-seat-invite output{display:block;overflow-wrap:anywhere;font-variant-ligatures:none;user-select:all}
794
+ .chapter-journey .member-named-seat-invite .journey-actions{margin-top:0}
788
795
  @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}}
789
796
  `;
790
797
  function JourneyFrame({ children }) {
@@ -860,7 +867,7 @@ function MemberRestart(props) {
860
867
  }
861
868
 
862
869
  // src/ui/members.tsx
863
- import { useEffect as useEffect6, useState as useState12 } from "preact/hooks";
870
+ import { useEffect as useEffect6, useState as useState13 } from "preact/hooks";
864
871
 
865
872
  // src/ui/reschedule.tsx
866
873
  import { useState as useState8 } from "preact/hooks";
@@ -1035,8 +1042,61 @@ function GiftPurchases(props) {
1035
1042
  var MemberGifts = GiftPurchases;
1036
1043
 
1037
1044
  // src/ui/member-named-seat.tsx
1038
- import { useEffect as useEffect4, useState as useState10 } from "preact/hooks";
1039
- import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs13 } from "preact/jsx-runtime";
1045
+ import { useEffect as useEffect4, useState as useState11 } from "preact/hooks";
1046
+
1047
+ // src/ui/named-seat-invitation-link.tsx
1048
+ import { useState as useState10 } from "preact/hooks";
1049
+ import { jsx as jsx14, jsxs as jsxs13 } from "preact/jsx-runtime";
1050
+ var namedSeatInvitationShareable = (seat) => seat.status === "pending_acceptance" && seat.invitationHeld !== true && seat.acceptedAt === void 0 && seat.recipientState === "invited";
1051
+ function namedSeatInvitationUrl(seat, origin, joinPath = "/join") {
1052
+ const url = new URL(joinPath, origin);
1053
+ url.searchParams.set("seat", seat.seatId);
1054
+ return url.href;
1055
+ }
1056
+ function namedSeatInvitationMessage(seat, url, chapterName) {
1057
+ const first = seat.recipientName.trim().split(/\s+/)[0] || seat.recipientName;
1058
+ return [
1059
+ `Hi ${first},`,
1060
+ "",
1061
+ `I've given you ${chapterName ? `a membership at ${chapterName}` : "a membership"}. Open this link and sign in with ${seat.recipientEmail} to accept it:`,
1062
+ url,
1063
+ "",
1064
+ "The invitation is for you alone, and the link only works with that email address."
1065
+ ].join("\n");
1066
+ }
1067
+ function NamedSeatInvitationLink(props) {
1068
+ const [note, setNote] = useState10("");
1069
+ if (!namedSeatInvitationShareable(props.seat)) return null;
1070
+ const origin = props.origin ?? (typeof window !== "undefined" ? window.location.origin : "");
1071
+ if (!origin) return null;
1072
+ const url = namedSeatInvitationUrl(props.seat, origin, props.joinPath);
1073
+ const copy = async (text, what) => {
1074
+ try {
1075
+ await navigator.clipboard.writeText(text);
1076
+ setNote(`${what} copied. Paste it into your email to ${props.seat.recipientName}.`);
1077
+ } catch {
1078
+ setNote("Copying is blocked here. Select the link above and copy it yourself.");
1079
+ }
1080
+ };
1081
+ return /* @__PURE__ */ jsxs13("div", { className: "member-named-seat-invite", "aria-label": "Send the invitation yourself", children: [
1082
+ /* @__PURE__ */ jsxs13("p", { children: [
1083
+ "Prefer to send the invitation yourself? Copy the link into an email to ",
1084
+ props.seat.recipientName,
1085
+ ". It opens only for ",
1086
+ props.seat.recipientEmail,
1087
+ "."
1088
+ ] }),
1089
+ /* @__PURE__ */ jsx14("output", { className: "member-named-seat-link", children: url }),
1090
+ /* @__PURE__ */ jsxs13("div", { className: "journey-actions", children: [
1091
+ /* @__PURE__ */ jsx14("button", { type: "button", className: "btn secondary", onClick: () => void copy(url, "Link"), children: "Copy invitation link" }),
1092
+ /* @__PURE__ */ jsx14("button", { type: "button", className: "btn secondary", onClick: () => void copy(namedSeatInvitationMessage(props.seat, url, props.chapterName), "Message"), children: "Copy a ready-to-send message" })
1093
+ ] }),
1094
+ note ? /* @__PURE__ */ jsx14("p", { role: "status", children: note }) : null
1095
+ ] });
1096
+ }
1097
+
1098
+ // src/ui/member-named-seat.tsx
1099
+ import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs14 } from "preact/jsx-runtime";
1040
1100
  var NAMED_SEAT_RECIPIENT_WORDS = {
1041
1101
  payment_pending: "payment in progress",
1042
1102
  invited: "invited, waiting for them to accept",
@@ -1049,7 +1109,7 @@ var NAMED_SEAT_RECIPIENT_WORDS = {
1049
1109
  var day = (at) => new Date(at).toLocaleDateString("en-US", { timeZone: "UTC" });
1050
1110
  function NamedSeatRecipientLine({ seat }) {
1051
1111
  const words = seat.invitationHeld ? "named; the invitation is sent once your membership is approved" : NAMED_SEAT_RECIPIENT_WORDS[seat.recipientState] ?? seat.status.replaceAll("_", " ");
1052
- return /* @__PURE__ */ jsxs13("p", { className: "member-named-seat-recipient", children: [
1112
+ return /* @__PURE__ */ jsxs14("p", { className: "member-named-seat-recipient", children: [
1053
1113
  seat.recipientName,
1054
1114
  " \xB7 ",
1055
1115
  seat.recipientEmail,
@@ -1059,10 +1119,10 @@ function NamedSeatRecipientLine({ seat }) {
1059
1119
  ] });
1060
1120
  }
1061
1121
  function NamedSeatPurchase({ api }) {
1062
- const [data, setData] = useState10(null), [error, setError] = useState10("");
1063
- const [name, setName] = useState10(""), [email, setEmail] = useState10(""), [reviewing, setReviewing] = useState10(false);
1064
- const [terms, setTerms] = useState10(false), [pending, setPending] = useState10(false), [granting, setGranting] = useState10(false);
1065
- const [renaming, setRenaming] = useState10(false), [nextName, setNextName] = useState10(""), [nextEmail, setNextEmail] = useState10("");
1122
+ const [data, setData] = useState11(null), [error, setError] = useState11("");
1123
+ const [name, setName] = useState11(""), [email, setEmail] = useState11(""), [reviewing, setReviewing] = useState11(false);
1124
+ const [terms, setTerms] = useState11(false), [pending, setPending] = useState11(false), [granting, setGranting] = useState11(false);
1125
+ const [renaming, setRenaming] = useState11(false), [nextName, setNextName] = useState11(""), [nextEmail, setNextEmail] = useState11("");
1066
1126
  const load = async () => {
1067
1127
  try {
1068
1128
  const value = await api("/api/named-seat");
@@ -1117,38 +1177,41 @@ function NamedSeatPurchase({ api }) {
1117
1177
  setGranting(false);
1118
1178
  }
1119
1179
  };
1120
- return /* @__PURE__ */ jsx14(JourneyFrame, { children: /* @__PURE__ */ jsxs13("section", { className: "card member-named-seat", "aria-label": "Named additional seat", children: [
1121
- /* @__PURE__ */ jsx14("h2", { children: "Named additional seat" }),
1122
- error ? /* @__PURE__ */ jsx14("p", { role: "alert", children: error }) : null,
1123
- data ? /* @__PURE__ */ jsxs13(Fragment3, { children: [
1124
- data.seat ? /* @__PURE__ */ jsx14(NamedSeatRecipientLine, { seat: data.seat }) : null,
1125
- data.seat?.regiftable && !renaming ? /* @__PURE__ */ jsx14("button", { className: "btn secondary", type: "button", onClick: () => {
1180
+ return /* @__PURE__ */ jsx15(JourneyFrame, { children: /* @__PURE__ */ jsxs14("section", { className: "card member-named-seat", "aria-label": "Named additional seat", children: [
1181
+ /* @__PURE__ */ jsx15("h2", { children: "Named additional seat" }),
1182
+ error ? /* @__PURE__ */ jsx15("p", { role: "alert", children: error }) : null,
1183
+ data ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
1184
+ data.seat ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
1185
+ /* @__PURE__ */ jsx15(NamedSeatRecipientLine, { seat: data.seat }),
1186
+ /* @__PURE__ */ jsx15(NamedSeatInvitationLink, { seat: data.seat })
1187
+ ] }) : null,
1188
+ data.seat?.regiftable && !renaming ? /* @__PURE__ */ jsx15("button", { className: "btn secondary", type: "button", onClick: () => {
1126
1189
  setRenaming(true);
1127
1190
  setNextName("");
1128
1191
  setNextEmail("");
1129
1192
  }, children: "Give the seat to someone else" }) : null,
1130
- data.seat?.regiftable && renaming ? /* @__PURE__ */ jsxs13("form", { className: "member-named-seat-regift", "aria-label": "Give the seat to someone else", onSubmit: (event) => void regift(event), children: [
1131
- /* @__PURE__ */ jsxs13("p", { children: [
1193
+ data.seat?.regiftable && renaming ? /* @__PURE__ */ jsxs14("form", { className: "member-named-seat-regift", "aria-label": "Give the seat to someone else", onSubmit: (event) => void regift(event), children: [
1194
+ /* @__PURE__ */ jsxs14("p", { children: [
1132
1195
  "The seat moves to the person you name here. ",
1133
1196
  data.seat.recipientName,
1134
1197
  "'s invitation stops working, and nothing is charged or refunded."
1135
1198
  ] }),
1136
- /* @__PURE__ */ jsxs13("label", { children: [
1199
+ /* @__PURE__ */ jsxs14("label", { children: [
1137
1200
  "New recipient name",
1138
- /* @__PURE__ */ jsx14("input", { required: true, maxLength: 160, value: nextName, onInput: (event) => setNextName(event.currentTarget.value) })
1201
+ /* @__PURE__ */ jsx15("input", { required: true, maxLength: 160, value: nextName, onInput: (event) => setNextName(event.currentTarget.value) })
1139
1202
  ] }),
1140
- /* @__PURE__ */ jsxs13("label", { children: [
1203
+ /* @__PURE__ */ jsxs14("label", { children: [
1141
1204
  "New recipient email",
1142
- /* @__PURE__ */ jsx14("input", { required: true, type: "email", maxLength: 254, value: nextEmail, onInput: (event) => setNextEmail(event.currentTarget.value) })
1205
+ /* @__PURE__ */ jsx15("input", { required: true, type: "email", maxLength: 254, value: nextEmail, onInput: (event) => setNextEmail(event.currentTarget.value) })
1143
1206
  ] }),
1144
- /* @__PURE__ */ jsx14("button", { className: "btn primary", type: "submit", disabled: granting, children: granting ? "Changing the recipient\u2026" : "Give the seat to this person" }),
1145
- /* @__PURE__ */ jsxs13("button", { className: "btn secondary", type: "button", disabled: granting, onClick: () => setRenaming(false), children: [
1207
+ /* @__PURE__ */ jsx15("button", { className: "btn primary", type: "submit", disabled: granting, children: granting ? "Changing the recipient\u2026" : "Give the seat to this person" }),
1208
+ /* @__PURE__ */ jsxs14("button", { className: "btn secondary", type: "button", disabled: granting, onClick: () => setRenaming(false), children: [
1146
1209
  "Keep ",
1147
1210
  data.seat.recipientName
1148
1211
  ] })
1149
1212
  ] }) : null,
1150
- data.eligible ? /* @__PURE__ */ jsxs13(Fragment3, { children: [
1151
- /* @__PURE__ */ jsxs13("p", { children: [
1213
+ data.eligible ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
1214
+ /* @__PURE__ */ jsxs14("p", { children: [
1152
1215
  data.included ? "Included with your membership at no charge." : `${money} paid in full now.`,
1153
1216
  " This seat ",
1154
1217
  data.autoRenew ? "renews with your primary membership" : "ends with your primary membership",
@@ -1159,39 +1222,39 @@ function NamedSeatPurchase({ api }) {
1159
1222
  " ",
1160
1223
  "It belongs to one named person and cannot be reassigned."
1161
1224
  ] }),
1162
- /* @__PURE__ */ jsx14("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." }),
1163
- !reviewing ? /* @__PURE__ */ jsxs13("form", { onSubmit: (event) => {
1225
+ /* @__PURE__ */ jsx15("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." }),
1226
+ !reviewing ? /* @__PURE__ */ jsxs14("form", { onSubmit: (event) => {
1164
1227
  event.preventDefault();
1165
1228
  setReviewing(true);
1166
1229
  setTerms(false);
1167
1230
  }, children: [
1168
- /* @__PURE__ */ jsxs13("label", { children: [
1231
+ /* @__PURE__ */ jsxs14("label", { children: [
1169
1232
  "Recipient name",
1170
- /* @__PURE__ */ jsx14("input", { required: true, maxLength: 160, value: name, disabled: Boolean(data.seat), onInput: (event) => setName(event.currentTarget.value) })
1233
+ /* @__PURE__ */ jsx15("input", { required: true, maxLength: 160, value: name, disabled: Boolean(data.seat), onInput: (event) => setName(event.currentTarget.value) })
1171
1234
  ] }),
1172
- /* @__PURE__ */ jsxs13("label", { children: [
1235
+ /* @__PURE__ */ jsxs14("label", { children: [
1173
1236
  "Recipient email",
1174
- /* @__PURE__ */ jsx14("input", { required: true, type: "email", maxLength: 254, value: email, disabled: Boolean(data.seat), onInput: (event) => setEmail(event.currentTarget.value) })
1237
+ /* @__PURE__ */ jsx15("input", { required: true, type: "email", maxLength: 254, value: email, disabled: Boolean(data.seat), onInput: (event) => setEmail(event.currentTarget.value) })
1175
1238
  ] }),
1176
- /* @__PURE__ */ jsx14("button", { className: "btn primary", type: "submit", children: "Review named seat" })
1177
- ] }) : /* @__PURE__ */ jsxs13(Fragment3, { children: [
1178
- /* @__PURE__ */ jsxs13("p", { children: [
1239
+ /* @__PURE__ */ jsx15("button", { className: "btn primary", type: "submit", children: "Review named seat" })
1240
+ ] }) : /* @__PURE__ */ jsxs14(Fragment3, { children: [
1241
+ /* @__PURE__ */ jsxs14("p", { children: [
1179
1242
  "For ",
1180
1243
  name,
1181
1244
  " \xB7 ",
1182
1245
  email
1183
1246
  ] }),
1184
- /* @__PURE__ */ jsx14("button", { className: "btn secondary", type: "button", onClick: () => {
1247
+ /* @__PURE__ */ jsx15("button", { className: "btn secondary", type: "button", onClick: () => {
1185
1248
  setReviewing(false);
1186
1249
  setTerms(false);
1187
1250
  void load();
1188
1251
  }, children: "Back to recipient" }),
1189
- /* @__PURE__ */ jsxs13("label", { className: "journey-consent", children: [
1190
- /* @__PURE__ */ jsx14("input", { type: "checkbox", checked: terms, onChange: (event) => setTerms(event.currentTarget.checked) }),
1191
- /* @__PURE__ */ jsx14("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." })
1252
+ /* @__PURE__ */ jsxs14("label", { className: "journey-consent", children: [
1253
+ /* @__PURE__ */ jsx15("input", { type: "checkbox", checked: terms, onChange: (event) => setTerms(event.currentTarget.checked) }),
1254
+ /* @__PURE__ */ jsx15("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." })
1192
1255
  ] }),
1193
- terms && data.included ? /* @__PURE__ */ jsx14("button", { className: "btn primary", type: "button", disabled: granting, onClick: () => void grant(), children: granting ? "Sending the invitation\u2026" : "Send the invitation" }) : null,
1194
- terms && !data.included ? /* @__PURE__ */ jsx14(
1256
+ terms && data.included ? /* @__PURE__ */ jsx15("button", { className: "btn primary", type: "button", disabled: granting, onClick: () => void grant(), children: granting ? "Sending the invitation\u2026" : "Send the invitation" }) : null,
1257
+ terms && !data.included ? /* @__PURE__ */ jsx15(
1195
1258
  PaymentStep,
1196
1259
  {
1197
1260
  applicationId: data.membershipId,
@@ -1206,17 +1269,17 @@ function NamedSeatPurchase({ api }) {
1206
1269
  }
1207
1270
  ) : null
1208
1271
  ] })
1209
- ] }) : !data.seat ? /* @__PURE__ */ jsx14("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,
1210
- pending ? /* @__PURE__ */ jsx14("p", { role: "status", children: "Payment confirmation is being reconciled. The recipient\u2019s access begins only after their own acceptance and approval." }) : null
1211
- ] }) : !error ? /* @__PURE__ */ jsx14("p", { children: "Loading your seat terms\u2026" }) : null,
1212
- /* @__PURE__ */ jsx14("button", { className: "btn secondary", onClick: () => void load(), children: "Refresh seat status" })
1272
+ ] }) : !data.seat ? /* @__PURE__ */ jsx15("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,
1273
+ pending ? /* @__PURE__ */ jsx15("p", { role: "status", children: "Payment confirmation is being reconciled. The recipient\u2019s access begins only after their own acceptance and approval." }) : null
1274
+ ] }) : !error ? /* @__PURE__ */ jsx15("p", { children: "Loading your seat terms\u2026" }) : null,
1275
+ /* @__PURE__ */ jsx15("button", { className: "btn secondary", onClick: () => void load(), children: "Refresh seat status" })
1213
1276
  ] }) });
1214
1277
  }
1215
1278
 
1216
1279
  // src/ui/member-content.tsx
1217
- import { useEffect as useEffect5, useMemo as useMemo2, useState as useState11 } from "preact/hooks";
1280
+ import { useEffect as useEffect5, useMemo as useMemo2, useState as useState12 } from "preact/hooks";
1218
1281
  import { Markdown } from "@odla-ai/ui/components";
1219
- import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs14 } from "preact/jsx-runtime";
1282
+ import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs15 } from "preact/jsx-runtime";
1220
1283
  var pageLabel = (page) => `${page.title}${page.access === "locked" ? " \xB7 Locked" : ""}`;
1221
1284
  function MemberContentArea(props) {
1222
1285
  const {
@@ -1224,12 +1287,12 @@ function MemberContentArea(props) {
1224
1287
  path = "/api/member-content",
1225
1288
  upsellHref,
1226
1289
  onUpsell,
1227
- loadingContent = /* @__PURE__ */ jsx15("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
1228
- emptyContent = /* @__PURE__ */ jsx15("p", { className: "meeting-note", children: "No member pages have been published yet." })
1290
+ loadingContent = /* @__PURE__ */ jsx16("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
1291
+ emptyContent = /* @__PURE__ */ jsx16("p", { className: "meeting-note", children: "No member pages have been published yet." })
1229
1292
  } = props;
1230
- const [data, setData] = useState11(props.initialData ?? null);
1231
- const [error, setError] = useState11(null);
1232
- const [selectedId, setSelectedId] = useState11(
1293
+ const [data, setData] = useState12(props.initialData ?? null);
1294
+ const [error, setError] = useState12(null);
1295
+ const [selectedId, setSelectedId] = useState12(
1233
1296
  props.initialPageId ?? props.initialData?.pages[0]?.id ?? ""
1234
1297
  );
1235
1298
  useEffect5(() => {
@@ -1254,18 +1317,18 @@ function MemberContentArea(props) {
1254
1317
  }
1255
1318
  return [...result.entries()];
1256
1319
  }, [data]);
1257
- if (error) return /* @__PURE__ */ jsxs14("p", { className: "meeting-note", role: "alert", children: [
1320
+ if (error) return /* @__PURE__ */ jsxs15("p", { className: "meeting-note", role: "alert", children: [
1258
1321
  "Member pages could not be loaded: ",
1259
1322
  error
1260
1323
  ] });
1261
- if (!data) return /* @__PURE__ */ jsx15(Fragment4, { children: loadingContent });
1262
- if (data.pages.length === 0) return /* @__PURE__ */ jsx15(Fragment4, { children: emptyContent });
1324
+ if (!data) return /* @__PURE__ */ jsx16(Fragment4, { children: loadingContent });
1325
+ if (data.pages.length === 0) return /* @__PURE__ */ jsx16(Fragment4, { children: emptyContent });
1263
1326
  const selected = data.pages.find((page) => page.id === selectedId) ?? data.pages[0];
1264
1327
  const href = selected.upsell && upsellHref ? upsellHref(selected.upsell.tierId, selected) : void 0;
1265
- return /* @__PURE__ */ jsxs14("div", { className: "chapter-member-content", "data-member-content": true, children: [
1266
- /* @__PURE__ */ jsx15("nav", { className: "chapter-member-content-nav", "aria-label": "Member pages", children: sections.map(([section, pages]) => /* @__PURE__ */ jsxs14("section", { className: "chapter-member-content-section", children: [
1267
- /* @__PURE__ */ jsx15("h2", { children: section }),
1268
- /* @__PURE__ */ jsx15("ul", { children: pages.map((page) => /* @__PURE__ */ jsx15("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx15(
1328
+ return /* @__PURE__ */ jsxs15("div", { className: "chapter-member-content", "data-member-content": true, children: [
1329
+ /* @__PURE__ */ jsx16("nav", { className: "chapter-member-content-nav", "aria-label": "Member pages", children: sections.map(([section, pages]) => /* @__PURE__ */ jsxs15("section", { className: "chapter-member-content-section", children: [
1330
+ /* @__PURE__ */ jsx16("h2", { children: section }),
1331
+ /* @__PURE__ */ jsx16("ul", { children: pages.map((page) => /* @__PURE__ */ jsx16("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx16(
1269
1332
  "button",
1270
1333
  {
1271
1334
  type: "button",
@@ -1275,23 +1338,23 @@ function MemberContentArea(props) {
1275
1338
  }
1276
1339
  ) }, page.id)) })
1277
1340
  ] }, section)) }),
1278
- /* @__PURE__ */ jsxs14("article", { className: "chapter-member-content-page", "data-access": selected.access, children: [
1279
- /* @__PURE__ */ jsxs14("header", { children: [
1280
- /* @__PURE__ */ jsxs14("div", { className: "card-label", children: [
1341
+ /* @__PURE__ */ jsxs15("article", { className: "chapter-member-content-page", "data-access": selected.access, children: [
1342
+ /* @__PURE__ */ jsxs15("header", { children: [
1343
+ /* @__PURE__ */ jsxs15("div", { className: "card-label", children: [
1281
1344
  selected.source.type === "parent" ? "Parent" : "Chapter",
1282
1345
  " \xB7 ",
1283
1346
  selected.access
1284
1347
  ] }),
1285
- /* @__PURE__ */ jsx15("h1", { children: selected.title }),
1286
- selected.summary ? /* @__PURE__ */ jsx15("p", { children: selected.summary }) : null
1348
+ /* @__PURE__ */ jsx16("h1", { children: selected.title }),
1349
+ selected.summary ? /* @__PURE__ */ jsx16("p", { children: selected.summary }) : null
1287
1350
  ] }),
1288
- selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx15(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs14("div", { className: "chapter-member-content-locked", children: [
1289
- selected.teaserMarkdown ? /* @__PURE__ */ jsx15(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx15("p", { children: "This page is not included in your current membership." }),
1290
- selected.upsell ? /* @__PURE__ */ jsxs14("aside", { className: "chapter-member-content-upsell", "aria-label": selected.upsell.label ?? "Membership option", children: [
1291
- /* @__PURE__ */ jsx15("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
1292
- /* @__PURE__ */ jsx15("p", { children: fmtMoney(selected.upsell.priceCents) }),
1293
- selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx15(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
1294
- href ? /* @__PURE__ */ jsx15("a", { className: "btn primary", href, children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : onUpsell ? /* @__PURE__ */ jsx15("button", { className: "btn primary", type: "button", onClick: () => onUpsell(selected.upsell.tierId, selected), children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : null
1351
+ selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx16(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs15("div", { className: "chapter-member-content-locked", children: [
1352
+ selected.teaserMarkdown ? /* @__PURE__ */ jsx16(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx16("p", { children: "This page is not included in your current membership." }),
1353
+ selected.upsell ? /* @__PURE__ */ jsxs15("aside", { className: "chapter-member-content-upsell", "aria-label": selected.upsell.label ?? "Membership option", children: [
1354
+ /* @__PURE__ */ jsx16("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
1355
+ /* @__PURE__ */ jsx16("p", { children: fmtMoney(selected.upsell.priceCents) }),
1356
+ selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx16(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
1357
+ href ? /* @__PURE__ */ jsx16("a", { className: "btn primary", href, children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : onUpsell ? /* @__PURE__ */ jsx16("button", { className: "btn primary", type: "button", onClick: () => onUpsell(selected.upsell.tierId, selected), children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : null
1295
1358
  ] }) : null
1296
1359
  ] })
1297
1360
  ] })
@@ -1299,12 +1362,12 @@ function MemberContentArea(props) {
1299
1362
  }
1300
1363
 
1301
1364
  // src/ui/members.tsx
1302
- import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs15 } from "preact/jsx-runtime";
1365
+ import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs16 } from "preact/jsx-runtime";
1303
1366
  function card(copy, kicker, body) {
1304
- return /* @__PURE__ */ jsxs15("div", { className: "card", children: [
1305
- /* @__PURE__ */ jsx16("div", { className: "card-label", children: copy.provisional.cardLabel }),
1306
- /* @__PURE__ */ jsxs15("div", { className: "meeting-block", children: [
1307
- /* @__PURE__ */ jsx16("div", { className: "meeting-kicker", children: kicker }),
1367
+ return /* @__PURE__ */ jsxs16("div", { className: "card", children: [
1368
+ /* @__PURE__ */ jsx17("div", { className: "card-label", children: copy.provisional.cardLabel }),
1369
+ /* @__PURE__ */ jsxs16("div", { className: "meeting-block", children: [
1370
+ /* @__PURE__ */ jsx17("div", { className: "meeting-kicker", children: kicker }),
1308
1371
  body
1309
1372
  ] })
1310
1373
  ] });
@@ -1315,9 +1378,9 @@ function ProvisionalCard(props) {
1315
1378
  return card(
1316
1379
  copy,
1317
1380
  copy.provisional.applicationNeeded,
1318
- /* @__PURE__ */ jsxs15(Fragment5, { children: [
1319
- /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
1320
- /* @__PURE__ */ jsx16("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
1381
+ /* @__PURE__ */ jsxs16(Fragment5, { children: [
1382
+ /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
1383
+ /* @__PURE__ */ jsx17("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
1321
1384
  ] })
1322
1385
  );
1323
1386
  }
@@ -1325,19 +1388,19 @@ function ProvisionalCard(props) {
1325
1388
  return card(
1326
1389
  copy,
1327
1390
  copy.provisional.refunded,
1328
- /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.refundedBody })
1391
+ /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: copy.provisional.refundedBody })
1329
1392
  );
1330
1393
  }
1331
- const membership = application.paid ? /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
1394
+ const membership = application.paid ? /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
1332
1395
  if (application.meetingAt) {
1333
1396
  return card(
1334
1397
  copy,
1335
1398
  copy.provisional.introductionCall,
1336
- /* @__PURE__ */ jsxs15(Fragment5, { children: [
1337
- /* @__PURE__ */ jsx16("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
1338
- /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
1339
- application.meetUrl ? /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: /* @__PURE__ */ jsx16("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
1340
- /* @__PURE__ */ jsx16(
1399
+ /* @__PURE__ */ jsxs16(Fragment5, { children: [
1400
+ /* @__PURE__ */ jsx17("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
1401
+ /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
1402
+ application.meetUrl ? /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: /* @__PURE__ */ jsx17("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
1403
+ /* @__PURE__ */ jsx17(
1341
1404
  Rescheduler,
1342
1405
  {
1343
1406
  api,
@@ -1354,9 +1417,9 @@ function ProvisionalCard(props) {
1354
1417
  return card(
1355
1418
  copy,
1356
1419
  copy.provisional.bookCall,
1357
- /* @__PURE__ */ jsxs15(Fragment5, { children: [
1358
- /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
1359
- /* @__PURE__ */ jsx16(
1420
+ /* @__PURE__ */ jsxs16(Fragment5, { children: [
1421
+ /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
1422
+ /* @__PURE__ */ jsx17(
1360
1423
  Rescheduler,
1361
1424
  {
1362
1425
  api,
@@ -1383,8 +1446,8 @@ function MembersArea(props) {
1383
1446
  renderProvisional
1384
1447
  } = props;
1385
1448
  const copy = props.copy ?? inheritedCopy.members;
1386
- const [me, setMe] = useState12(null);
1387
- const [error, setError] = useState12(false);
1449
+ const [me, setMe] = useState13(null);
1450
+ const [error, setError] = useState13(false);
1388
1451
  const reload = async () => {
1389
1452
  try {
1390
1453
  setMe(await api("/api/me"));
@@ -1395,22 +1458,22 @@ function MembersArea(props) {
1395
1458
  useEffect6(() => {
1396
1459
  void reload();
1397
1460
  }, []);
1398
- if (error) return /* @__PURE__ */ jsx16("p", { className: "meeting-note", children: copy.loadFailed });
1399
- if (!me) return /* @__PURE__ */ jsx16("p", { className: "meeting-note", children: inheritedCopy.common.loading });
1461
+ if (error) return /* @__PURE__ */ jsx17("p", { className: "meeting-note", children: copy.loadFailed });
1462
+ if (!me) return /* @__PURE__ */ jsx17("p", { className: "meeting-note", children: inheritedCopy.common.loading });
1400
1463
  const role = me.role || "provisional";
1401
- return /* @__PURE__ */ jsxs15(Fragment5, { children: [
1402
- /* @__PURE__ */ jsxs15("div", { className: "card", children: [
1403
- /* @__PURE__ */ jsxs15("div", { className: "member-row", children: [
1404
- /* @__PURE__ */ jsx16("span", { className: "member-email", children: me.email }),
1405
- /* @__PURE__ */ jsx16("span", { className: "role-badge " + role, children: role })
1464
+ return /* @__PURE__ */ jsxs16(Fragment5, { children: [
1465
+ /* @__PURE__ */ jsxs16("div", { className: "card", children: [
1466
+ /* @__PURE__ */ jsxs16("div", { className: "member-row", children: [
1467
+ /* @__PURE__ */ jsx17("span", { className: "member-email", children: me.email }),
1468
+ /* @__PURE__ */ jsx17("span", { className: "role-badge " + role, children: role })
1406
1469
  ] }),
1407
- /* @__PURE__ */ jsxs15("div", { className: "account-actions", children: [
1408
- /* @__PURE__ */ jsx16("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
1409
- me.authorized || me.superAdmin ? /* @__PURE__ */ jsx16("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
1470
+ /* @__PURE__ */ jsxs16("div", { className: "account-actions", children: [
1471
+ /* @__PURE__ */ jsx17("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
1472
+ me.authorized || me.superAdmin ? /* @__PURE__ */ jsx17("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
1410
1473
  ] })
1411
1474
  ] }),
1412
- me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */ jsx16(MemberRestart, { api, application: me.application, applicationId: me.membershipRestart.applicationId, onComplete: reload }) : me.memberAccess !== true ? (() => {
1413
- const defaultContent = /* @__PURE__ */ jsx16(
1475
+ me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */ jsx17(MemberRestart, { api, application: me.application, applicationId: me.membershipRestart.applicationId, onComplete: reload }) : me.memberAccess !== true ? (() => {
1476
+ const defaultContent = /* @__PURE__ */ jsx17(
1414
1477
  ProvisionalCard,
1415
1478
  {
1416
1479
  api,
@@ -1427,31 +1490,43 @@ function MembersArea(props) {
1427
1490
  reload,
1428
1491
  defaultContent
1429
1492
  }) ?? defaultContent;
1430
- })() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx16(
1493
+ })() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx17(
1431
1494
  MemberContentArea,
1432
1495
  {
1433
1496
  api,
1434
1497
  ...memberPages === true ? {} : memberPages
1435
1498
  }
1436
- ) : /* @__PURE__ */ jsx16("div", { className: "card", children: /* @__PURE__ */ jsx16("div", { className: "card-label", children: copy.full.welcome }) })),
1437
- /* @__PURE__ */ jsx16(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment }),
1438
- me.namedSeatsEnabled ? /* @__PURE__ */ jsx16(NamedSeatPurchase, { api }) : null
1499
+ ) : /* @__PURE__ */ jsx17("div", { className: "card", children: /* @__PURE__ */ jsx17("div", { className: "card-label", children: copy.full.welcome }) })),
1500
+ /* @__PURE__ */ jsx17(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment }),
1501
+ me.namedSeatsEnabled ? /* @__PURE__ */ jsx17(NamedSeatPurchase, { api }) : null
1439
1502
  ] });
1440
1503
  }
1441
1504
 
1442
1505
  // src/ui/join.tsx
1443
- import { useEffect as useEffect11, useRef as useRef7, useState as useState20 } from "preact/hooks";
1506
+ import { useEffect as useEffect11, useRef as useRef8, useState as useState21 } from "preact/hooks";
1444
1507
 
1445
1508
  // src/ui/join-booking.tsx
1446
- import { useEffect as useEffect7, useState as useState13 } from "preact/hooks";
1447
- import { jsx as jsx17, jsxs as jsxs16 } from "preact/jsx-runtime";
1509
+ import { useEffect as useEffect7, useRef as useRef6, useState as useState14 } from "preact/hooks";
1510
+ import { jsx as jsx18, jsxs as jsxs17 } from "preact/jsx-runtime";
1511
+ function useJoinSlotsPreload(active) {
1512
+ const preload = useRef6(null);
1513
+ useEffect7(() => {
1514
+ if (!active || preload.current) return;
1515
+ preload.current = Promise.resolve().then(() => fetch("/api/schedule/slots"));
1516
+ preload.current.catch(() => {
1517
+ preload.current = null;
1518
+ });
1519
+ }, [active]);
1520
+ return preload.current ?? void 0;
1521
+ }
1448
1522
  function JoinBooking(props) {
1449
1523
  const { applicationId, copy, onBooked, simulation } = props;
1450
- const [state, setState] = useState13(null);
1451
- const [msg, setMsg] = useState13(null);
1452
- const [busy, setBusy] = useState13(false);
1453
- const [selected, setSelected] = useState13(null);
1454
- const load = async () => {
1524
+ const [state, setState] = useState14(null);
1525
+ const [msg, setMsg] = useState14(null);
1526
+ const [busy, setBusy] = useState14(false);
1527
+ const [day2, setDay] = useState14(null);
1528
+ const [selected, setSelected] = useState14(null);
1529
+ const load = async (preloaded) => {
1455
1530
  setMsg(null);
1456
1531
  try {
1457
1532
  if (simulation) {
@@ -1463,7 +1538,7 @@ function JoinBooking(props) {
1463
1538
  setState({ slots: [...simulation.slots], timezone: simulation.timezone });
1464
1539
  return;
1465
1540
  }
1466
- const res = await fetch("/api/schedule/slots");
1541
+ const res = await (preloaded ?? fetch("/api/schedule/slots"));
1467
1542
  const data = await res.json();
1468
1543
  if (data.schedulingReady === false || !data.slots?.length) {
1469
1544
  setState(null);
@@ -1476,7 +1551,7 @@ function JoinBooking(props) {
1476
1551
  }
1477
1552
  };
1478
1553
  useEffect7(() => {
1479
- void load();
1554
+ void load(props.preload);
1480
1555
  }, [simulation]);
1481
1556
  const book = async () => {
1482
1557
  if (!selected) return;
@@ -1507,43 +1582,49 @@ function JoinBooking(props) {
1507
1582
  setBusy(false);
1508
1583
  }
1509
1584
  };
1510
- if (!state) return /* @__PURE__ */ jsx17("p", { className: "slots-status", children: msg ?? copy.loading });
1511
- return /* @__PURE__ */ jsxs16("div", { className: "join-book", children: [
1512
- /* @__PURE__ */ jsx17("h2", { children: copy.title ?? DEFAULT_JOIN_COPY.booking.title }),
1513
- /* @__PURE__ */ jsx17("p", { children: copy.intro ?? DEFAULT_JOIN_COPY.booking.intro }),
1514
- /* @__PURE__ */ jsx17(
1585
+ if (!state) return /* @__PURE__ */ jsx18("p", { className: "slots-status", children: msg ?? copy.loading });
1586
+ const hint = !day2 ? copy.pickDate ?? DEFAULT_JOIN_COPY.booking.pickDate : !selected ? copy.pickTime ?? DEFAULT_JOIN_COPY.booking.pickTime : null;
1587
+ return /* @__PURE__ */ jsxs17("div", { className: "join-book", children: [
1588
+ /* @__PURE__ */ jsx18("h2", { children: copy.title ?? DEFAULT_JOIN_COPY.booking.title }),
1589
+ /* @__PURE__ */ jsx18("p", { children: copy.intro ?? DEFAULT_JOIN_COPY.booking.intro }),
1590
+ /* @__PURE__ */ jsxs17("div", { className: "slot-confirm", children: [
1591
+ /* @__PURE__ */ jsx18("button", { className: "submit-btn", type: "button", disabled: busy || !selected, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
1592
+ hint ? /* @__PURE__ */ jsx18("p", { className: "slot-hint", role: "status", children: hint }) : null,
1593
+ msg ? /* @__PURE__ */ jsx18("p", { className: "step2-note", role: "alert", children: msg }) : null
1594
+ ] }),
1595
+ /* @__PURE__ */ jsx18(
1515
1596
  SlotPicker,
1516
1597
  {
1517
1598
  slots: state.slots,
1518
1599
  timezone: state.timezone,
1519
1600
  selectedStartAt: selected?.startAt,
1520
1601
  onPick: setSelected,
1521
- onDayChange: () => setSelected(null)
1602
+ initialDay: "none",
1603
+ onDayChange: (key) => {
1604
+ setDay(key);
1605
+ setSelected(null);
1606
+ }
1522
1607
  }
1523
- ),
1524
- /* @__PURE__ */ jsxs16("div", { className: "slot-confirm", hidden: !selected, children: [
1525
- /* @__PURE__ */ jsx17("button", { className: "submit-btn", disabled: busy, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
1526
- msg ? /* @__PURE__ */ jsx17("p", { className: "step2-note", children: msg }) : null
1527
- ] })
1608
+ )
1528
1609
  ] });
1529
1610
  }
1530
1611
 
1531
1612
  // src/ui/join-accepted.tsx
1532
- import { jsx as jsx18, jsxs as jsxs17 } from "preact/jsx-runtime";
1613
+ import { jsx as jsx19, jsxs as jsxs18 } from "preact/jsx-runtime";
1533
1614
  function JoinAccepted(props) {
1534
- return /* @__PURE__ */ jsxs17("div", { className: "join-done card", children: [
1535
- /* @__PURE__ */ jsx18("div", { className: "card-label", children: props.copy.accepted.label }),
1536
- /* @__PURE__ */ jsx18("p", { className: "meeting-note", children: props.copy.accepted.body }),
1537
- /* @__PURE__ */ jsx18("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
1615
+ return /* @__PURE__ */ jsxs18("div", { className: "join-done card", children: [
1616
+ /* @__PURE__ */ jsx19("div", { className: "card-label", children: props.copy.accepted.label }),
1617
+ /* @__PURE__ */ jsx19("p", { className: "meeting-note", children: props.copy.accepted.body }),
1618
+ /* @__PURE__ */ jsx19("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
1538
1619
  ] });
1539
1620
  }
1540
1621
 
1541
1622
  // src/ui/gift-claim-card.tsx
1542
- import { useState as useState14 } from "preact/hooks";
1543
- import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs18 } from "preact/jsx-runtime";
1623
+ import { useState as useState15 } from "preact/hooks";
1624
+ import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs19 } from "preact/jsx-runtime";
1544
1625
  function GiftClaimCard(props) {
1545
- const [code, setCode] = useState14(props.initialCode ?? "");
1546
- const [error, setError] = useState14(false);
1626
+ const [code, setCode] = useState15(props.initialCode ?? "");
1627
+ const [error, setError] = useState15(false);
1547
1628
  const rotate = async () => {
1548
1629
  if (!props.claimId) return;
1549
1630
  setError(false);
@@ -1556,27 +1637,27 @@ function GiftClaimCard(props) {
1556
1637
  if (response.ok && body.code) setCode(body.code);
1557
1638
  else setError(true);
1558
1639
  };
1559
- return /* @__PURE__ */ jsxs18("div", { className: "join-done card", children: [
1560
- /* @__PURE__ */ jsx19("div", { className: "card-label", children: props.copy.label }),
1561
- /* @__PURE__ */ jsx19("p", { className: "meeting-note", children: props.copy.body }),
1562
- code ? /* @__PURE__ */ jsxs18(Fragment6, { children: [
1563
- /* @__PURE__ */ jsx19("output", { className: "gift-code", children: code }),
1564
- /* @__PURE__ */ jsx19("p", { children: props.copy.save })
1640
+ return /* @__PURE__ */ jsxs19("div", { className: "join-done card", children: [
1641
+ /* @__PURE__ */ jsx20("div", { className: "card-label", children: props.copy.label }),
1642
+ /* @__PURE__ */ jsx20("p", { className: "meeting-note", children: props.copy.body }),
1643
+ code ? /* @__PURE__ */ jsxs19(Fragment6, { children: [
1644
+ /* @__PURE__ */ jsx20("output", { className: "gift-code", children: code }),
1645
+ /* @__PURE__ */ jsx20("p", { children: props.copy.save })
1565
1646
  ] }) : null,
1566
- !code && props.claimId ? /* @__PURE__ */ jsx19("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
1567
- error ? /* @__PURE__ */ jsx19("p", { role: "alert", children: props.copy.rotateFailed }) : null
1647
+ !code && props.claimId ? /* @__PURE__ */ jsx20("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
1648
+ error ? /* @__PURE__ */ jsx20("p", { role: "alert", children: props.copy.rotateFailed }) : null
1568
1649
  ] });
1569
1650
  }
1570
1651
 
1571
1652
  // src/ui/join-application-form.tsx
1572
- import { useRef as useRef6 } from "preact/hooks";
1653
+ import { useRef as useRef7 } from "preact/hooks";
1573
1654
 
1574
1655
  // src/ui/join-tiers.tsx
1575
- import { useState as useState15 } from "preact/hooks";
1576
- import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs19 } from "preact/jsx-runtime";
1656
+ import { useState as useState16 } from "preact/hooks";
1657
+ import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs20 } from "preact/jsx-runtime";
1577
1658
  var joinTierMoney = (cents, currency = "usd") => new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
1578
1659
  function useTierSelection(tiers, initialTierId) {
1579
- const [selectedTierId, setSelectedTierId] = useState15(() => {
1660
+ const [selectedTierId, setSelectedTierId] = useState16(() => {
1580
1661
  const preset = tiers.find((tier) => tier.id === initialTierId);
1581
1662
  if (preset) return preset.id;
1582
1663
  return tiers.length === 1 ? tiers[0].id : null;
@@ -1591,10 +1672,10 @@ function useTierSelection(tiers, initialTierId) {
1591
1672
  };
1592
1673
  }
1593
1674
  function TierPlaceholder(context) {
1594
- return /* @__PURE__ */ jsxs19("fieldset", { "data-chapter-placeholder": "tiers", children: [
1595
- /* @__PURE__ */ jsx20("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
1596
- context.tiers.map((tier) => /* @__PURE__ */ jsxs19("label", { children: [
1597
- /* @__PURE__ */ jsx20(
1675
+ return /* @__PURE__ */ jsxs20("fieldset", { "data-chapter-placeholder": "tiers", children: [
1676
+ /* @__PURE__ */ jsx21("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
1677
+ context.tiers.map((tier) => /* @__PURE__ */ jsxs20("label", { children: [
1678
+ /* @__PURE__ */ jsx21(
1598
1679
  "input",
1599
1680
  {
1600
1681
  type: "radio",
@@ -1605,13 +1686,13 @@ function TierPlaceholder(context) {
1605
1686
  }
1606
1687
  ),
1607
1688
  tier.name,
1608
- tier.founding ? /* @__PURE__ */ jsxs19(Fragment7, { children: [
1689
+ tier.founding ? /* @__PURE__ */ jsxs20(Fragment7, { children: [
1609
1690
  " \u2014 ",
1610
1691
  joinTierMoney(tier.founding.dueTodayCents),
1611
1692
  " founding member rate (list ",
1612
1693
  joinTierMoney(tier.priceCents),
1613
1694
  ")"
1614
- ] }) : tier.free ? " \u2014 free" : /* @__PURE__ */ jsxs19(Fragment7, { children: [
1695
+ ] }) : tier.free ? " \u2014 free" : /* @__PURE__ */ jsxs20(Fragment7, { children: [
1615
1696
  " \u2014 ",
1616
1697
  joinTierMoney(tier.priceCents)
1617
1698
  ] })
@@ -1623,12 +1704,12 @@ function tierNeedsPayment(selected, paymentsReady) {
1623
1704
  }
1624
1705
 
1625
1706
  // src/ui/join-application-form.tsx
1626
- import { jsx as jsx21, jsxs as jsxs20 } from "preact/jsx-runtime";
1707
+ import { jsx as jsx22, jsxs as jsxs21 } from "preact/jsx-runtime";
1627
1708
  function JoinApplicationForm({ props, copy, invitation, requestedSeat, tierSelection, giftOfferId, selectGift, submitting, error, submit }) {
1628
- const form = useRef6(null);
1709
+ const form = useRef7(null);
1629
1710
  const ready = useFormReadiness(form);
1630
1711
  const disabled = submitting || props.submitDisabled === true || !ready || !validJoinRecipient(props.payment?.initialNamedSeat);
1631
- return /* @__PURE__ */ jsxs20("form", { ref: form, className: "join-form", onSubmit: (event) => {
1712
+ return /* @__PURE__ */ jsxs21("form", { ref: form, className: "join-form", onSubmit: (event) => {
1632
1713
  if (!isFormReady(event.currentTarget)) {
1633
1714
  event.preventDefault();
1634
1715
  event.currentTarget.reportValidity();
@@ -1636,15 +1717,15 @@ function JoinApplicationForm({ props, copy, invitation, requestedSeat, tierSelec
1636
1717
  }
1637
1718
  void submit(event);
1638
1719
  }, children: [
1639
- !requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs20("fieldset", { children: [
1640
- /* @__PURE__ */ jsx21("legend", { children: copy.gift.optionsLabel }),
1641
- /* @__PURE__ */ jsx21("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => selectGift(null), children: copy.gift.chooseSelf }),
1642
- /* @__PURE__ */ jsx21(GiftOfferCards, { offers: props.config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: selectGift })
1720
+ !requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs21("fieldset", { children: [
1721
+ /* @__PURE__ */ jsx22("legend", { children: copy.gift.optionsLabel }),
1722
+ /* @__PURE__ */ jsx22("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => selectGift(null), children: copy.gift.chooseSelf }),
1723
+ /* @__PURE__ */ jsx22(GiftOfferCards, { offers: props.config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: selectGift })
1643
1724
  ] }) : null,
1644
1725
  !requestedSeat && (props.config.tiers?.length ?? 0) > 1 ? props.renderTiers?.(tierSelection) ?? TierPlaceholder(tierSelection) : null,
1645
1726
  typeof props.children === "function" ? props.children({ invitation }) : props.children,
1646
- error ? /* @__PURE__ */ jsx21("p", { className: "join-error", role: "alert", children: error }) : null,
1647
- props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */ jsx21(JoinSubmitButton, { disabled, children: submitting ? copy.form.submitting : copy.form.submit })
1727
+ error ? /* @__PURE__ */ jsx22("p", { className: "join-error", role: "alert", children: error }) : null,
1728
+ props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */ jsx22(JoinSubmitButton, { disabled, children: submitting ? copy.form.submitting : copy.form.submit })
1648
1729
  ] });
1649
1730
  }
1650
1731
 
@@ -1669,8 +1750,8 @@ function joinStateFromApplicationResponse(data, fallbackNeedsPayment, submittedG
1669
1750
 
1670
1751
  // src/ui/gift-code-redeemer.tsx
1671
1752
  import { InlineActionField } from "@odla-ai/ui/components";
1672
- import { useState as useState16 } from "preact/hooks";
1673
- import { Fragment as Fragment8, jsx as jsx22, jsxs as jsxs21 } from "preact/jsx-runtime";
1753
+ import { useState as useState17 } from "preact/hooks";
1754
+ import { Fragment as Fragment8, jsx as jsx23, jsxs as jsxs22 } from "preact/jsx-runtime";
1674
1755
  var GIFT_CODE_REDEEMER_CSS = `
1675
1756
  .gift-code-redeemer{container-type:inline-size;display:grid;gap:var(--ui-space-1,.35rem);margin:0}
1676
1757
  .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}
@@ -1685,10 +1766,10 @@ var GIFT_CODE_REDEEMER_CSS = `
1685
1766
  @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%}}
1686
1767
  `;
1687
1768
  function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
1688
- const [code, setCode] = useState16("");
1689
- const [loading, setLoading] = useState16(false);
1690
- const [message, setMessage] = useState16("");
1691
- const [messageTone, setMessageTone] = useState16("neutral");
1769
+ const [code, setCode] = useState17("");
1770
+ const [loading, setLoading] = useState17(false);
1771
+ const [message, setMessage] = useState17("");
1772
+ const [messageTone, setMessageTone] = useState17("neutral");
1692
1773
  const normalizedCode = code.trim();
1693
1774
  const redeem = async () => {
1694
1775
  if (!normalizedCode || loading) return;
@@ -1715,9 +1796,9 @@ function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
1715
1796
  setLoading(false);
1716
1797
  }
1717
1798
  };
1718
- return /* @__PURE__ */ jsxs21(Fragment8, { children: [
1719
- /* @__PURE__ */ jsx22("style", { children: GIFT_CODE_REDEEMER_CSS }),
1720
- /* @__PURE__ */ jsx22(
1799
+ return /* @__PURE__ */ jsxs22(Fragment8, { children: [
1800
+ /* @__PURE__ */ jsx23("style", { children: GIFT_CODE_REDEEMER_CSS }),
1801
+ /* @__PURE__ */ jsx23(
1721
1802
  InlineActionField,
1722
1803
  {
1723
1804
  id,
@@ -1773,12 +1854,12 @@ async function loadJoinResume(applicationId, fetcher = fetch) {
1773
1854
  }
1774
1855
 
1775
1856
  // src/ui/join-gift-claim.tsx
1776
- import { jsx as jsx23, jsxs as jsxs22 } from "preact/jsx-runtime";
1857
+ import { jsx as jsx24, jsxs as jsxs23 } from "preact/jsx-runtime";
1777
1858
  function JoinGiftClaim(props) {
1778
- return /* @__PURE__ */ jsxs22("section", { className: "join-gift-claim card", children: [
1779
- /* @__PURE__ */ jsx23("div", { className: "card-label", children: props.copy.claimTitle }),
1780
- /* @__PURE__ */ jsx23("p", { children: props.copy.claimBody }),
1781
- /* @__PURE__ */ jsx23(
1859
+ return /* @__PURE__ */ jsxs23("section", { className: "join-gift-claim card", children: [
1860
+ /* @__PURE__ */ jsx24("div", { className: "card-label", children: props.copy.claimTitle }),
1861
+ /* @__PURE__ */ jsx24("p", { children: props.copy.claimBody }),
1862
+ /* @__PURE__ */ jsx24(
1782
1863
  GiftCodeRedeemer,
1783
1864
  {
1784
1865
  api: props.api,
@@ -1802,21 +1883,21 @@ function JoinGiftClaim(props) {
1802
1883
  }
1803
1884
 
1804
1885
  // src/ui/join-named-seat.tsx
1805
- import { useState as useState17 } from "preact/hooks";
1806
- import { jsx as jsx24, jsxs as jsxs23 } from "preact/jsx-runtime";
1886
+ import { useState as useState18 } from "preact/hooks";
1887
+ import { jsx as jsx25, jsxs as jsxs24 } from "preact/jsx-runtime";
1807
1888
  function JoinNamedSeat(props) {
1808
1889
  const seatId = props.seatId ?? "";
1809
1890
  const inherited = useChapterCopy(), copy = props.copy ?? inherited.join.namedSeat;
1810
- const [accepted, setAccepted] = useState17(false), [busy, setBusy] = useState17(false), [error, setError] = useState17("");
1811
- return /* @__PURE__ */ jsxs23("section", { className: "join-named-seat card", children: [
1812
- /* @__PURE__ */ jsx24("h2", { children: copy.title }),
1813
- /* @__PURE__ */ jsx24("p", { children: copy.body }),
1814
- /* @__PURE__ */ jsxs23("label", { className: "journey-consent", children: [
1815
- /* @__PURE__ */ jsx24("input", { type: "checkbox", checked: accepted, disabled: busy, onChange: (event) => setAccepted(event.currentTarget.checked) }),
1816
- /* @__PURE__ */ jsx24("span", { children: copy.consent })
1891
+ const [accepted, setAccepted] = useState18(false), [busy, setBusy] = useState18(false), [error, setError] = useState18("");
1892
+ return /* @__PURE__ */ jsxs24("section", { className: "join-named-seat card", children: [
1893
+ /* @__PURE__ */ jsx25("h2", { children: copy.title }),
1894
+ /* @__PURE__ */ jsx25("p", { children: copy.body }),
1895
+ /* @__PURE__ */ jsxs24("label", { className: "journey-consent", children: [
1896
+ /* @__PURE__ */ jsx25("input", { type: "checkbox", checked: accepted, disabled: busy, onChange: (event) => setAccepted(event.currentTarget.checked) }),
1897
+ /* @__PURE__ */ jsx25("span", { children: copy.consent })
1817
1898
  ] }),
1818
- error ? /* @__PURE__ */ jsx24("p", { role: "alert", children: error }) : null,
1819
- /* @__PURE__ */ jsx24("button", { type: "button", className: "btn btn-primary", disabled: busy || !accepted || !seatId.trim(), onClick: async () => {
1899
+ error ? /* @__PURE__ */ jsx25("p", { role: "alert", children: error }) : null,
1900
+ /* @__PURE__ */ jsx25("button", { type: "button", className: "btn btn-primary", disabled: busy || !accepted || !seatId.trim(), onClick: async () => {
1820
1901
  setBusy(true);
1821
1902
  setError("");
1822
1903
  try {
@@ -1836,12 +1917,12 @@ function JoinNamedSeat(props) {
1836
1917
  }
1837
1918
 
1838
1919
  // src/ui/join-invitation.tsx
1839
- import { useEffect as useEffect8, useState as useState18 } from "preact/hooks";
1840
- import { jsx as jsx25, jsxs as jsxs24 } from "preact/jsx-runtime";
1920
+ import { useEffect as useEffect8, useState as useState19 } from "preact/hooks";
1921
+ import { jsx as jsx26, jsxs as jsxs25 } from "preact/jsx-runtime";
1841
1922
  function useJoinInvitation(seatId, api, fallback) {
1842
- const [invitation, setInvitation] = useState18(null);
1843
- const [error, setError] = useState18("");
1844
- const [revision, setRevision] = useState18(0);
1923
+ const [invitation, setInvitation] = useState19(null);
1924
+ const [error, setError] = useState19("");
1925
+ const [revision, setRevision] = useState19(0);
1845
1926
  useEffect8(() => {
1846
1927
  let live = true;
1847
1928
  setInvitation(null);
@@ -1864,9 +1945,9 @@ function useJoinInvitation(seatId, api, fallback) {
1864
1945
  return { invitation: invitation?.seatId === seatId ? invitation : null, error, retry: () => setRevision((value) => value + 1) };
1865
1946
  }
1866
1947
  function JoinInvitationNotice(props) {
1867
- return /* @__PURE__ */ jsxs24("aside", { className: "journey-invitation", "aria-label": props.copy.title, children: [
1868
- /* @__PURE__ */ jsx25("p", { children: /* @__PURE__ */ jsx25("strong", { children: formatChapterCopy(props.copy.from, { purchaserName: props.invitation.purchaserName }) }) }),
1869
- /* @__PURE__ */ jsx25("p", { children: formatChapterCopy(props.copy.prepaid, { tierName: props.tierName }) })
1948
+ return /* @__PURE__ */ jsxs25("aside", { className: "journey-invitation", "aria-label": props.copy.title, children: [
1949
+ /* @__PURE__ */ jsx26("p", { children: /* @__PURE__ */ jsx26("strong", { children: formatChapterCopy(props.copy.from, { purchaserName: props.invitation.purchaserName }) }) }),
1950
+ /* @__PURE__ */ jsx26("p", { children: formatChapterCopy(props.copy.prepaid, { tierName: props.tierName }) })
1870
1951
  ] });
1871
1952
  }
1872
1953
 
@@ -1906,14 +1987,14 @@ function useJoinPending(state, loadResume, setState) {
1906
1987
  }
1907
1988
 
1908
1989
  // src/ui/payment-receipt.tsx
1909
- import { useEffect as useEffect10, useState as useState19 } from "preact/hooks";
1910
- import { Fragment as Fragment9, jsx as jsx26, jsxs as jsxs25 } from "preact/jsx-runtime";
1990
+ import { useEffect as useEffect10, useState as useState20 } from "preact/hooks";
1991
+ import { Fragment as Fragment9, jsx as jsx27, jsxs as jsxs26 } from "preact/jsx-runtime";
1911
1992
  function PaymentReceiptCard({ applicationId }) {
1912
- const [receipt, setReceipt] = useState19(null);
1913
- const [error, setError] = useState19("");
1914
- const [revision, setRevision] = useState19(0);
1915
- const [emailState, setEmailState] = useState19("idle");
1916
- const [previewEmail, setPreviewEmail] = useState19(false);
1993
+ const [receipt, setReceipt] = useState20(null);
1994
+ const [error, setError] = useState20("");
1995
+ const [revision, setRevision] = useState20(0);
1996
+ const [emailState, setEmailState] = useState20("idle");
1997
+ const [previewEmail, setPreviewEmail] = useState20(false);
1917
1998
  const endpoint = `/api/payments/receipt?application=${encodeURIComponent(applicationId)}`;
1918
1999
  useEffect10(() => {
1919
2000
  let live = true, timer;
@@ -1941,9 +2022,9 @@ function PaymentReceiptCard({ applicationId }) {
1941
2022
  if (timer) clearTimeout(timer);
1942
2023
  };
1943
2024
  }, [endpoint, revision]);
1944
- if (!receipt) return error ? /* @__PURE__ */ jsxs25("section", { "aria-label": "Payment receipt", children: [
1945
- /* @__PURE__ */ jsx26("p", { role: "status", children: error }),
1946
- /* @__PURE__ */ jsx26("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Reload receipt" })
2025
+ if (!receipt) return error ? /* @__PURE__ */ jsxs26("section", { "aria-label": "Payment receipt", children: [
2026
+ /* @__PURE__ */ jsx27("p", { role: "status", children: error }),
2027
+ /* @__PURE__ */ jsx27("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Reload receipt" })
1947
2028
  ] }) : null;
1948
2029
  const money = (cents) => new Intl.NumberFormat("en-US", { style: "currency", currency: receipt.currency }).format(cents / 100);
1949
2030
  const email = async () => {
@@ -1960,38 +2041,38 @@ function PaymentReceiptCard({ applicationId }) {
1960
2041
  setError("We could not confirm email delivery. You can print or save your receipt.");
1961
2042
  }
1962
2043
  };
1963
- return /* @__PURE__ */ jsxs25("section", { className: "payment-receipt card", "aria-label": "Payment receipt", children: [
1964
- /* @__PURE__ */ jsx26("h2", { children: "Payment received" }),
1965
- /* @__PURE__ */ jsx26("p", { children: receipt.tierName }),
1966
- /* @__PURE__ */ jsxs25("dl", { className: "journey-summary", children: [
1967
- /* @__PURE__ */ jsx26("dt", { children: "Membership" }),
1968
- /* @__PURE__ */ jsx26("dd", { children: money(receipt.membershipCents) }),
1969
- receipt.namedSeat ? /* @__PURE__ */ jsxs25(Fragment9, { children: [
1970
- /* @__PURE__ */ jsxs25("dt", { children: [
2044
+ return /* @__PURE__ */ jsxs26("section", { className: "payment-receipt card", "aria-label": "Payment receipt", children: [
2045
+ /* @__PURE__ */ jsx27("h2", { children: "Payment received" }),
2046
+ /* @__PURE__ */ jsx27("p", { children: receipt.tierName }),
2047
+ /* @__PURE__ */ jsxs26("dl", { className: "journey-summary", children: [
2048
+ /* @__PURE__ */ jsx27("dt", { children: "Membership" }),
2049
+ /* @__PURE__ */ jsx27("dd", { children: money(receipt.membershipCents) }),
2050
+ receipt.namedSeat ? /* @__PURE__ */ jsxs26(Fragment9, { children: [
2051
+ /* @__PURE__ */ jsxs26("dt", { children: [
1971
2052
  "Additional member \u2014 ",
1972
2053
  receipt.namedSeat.recipientName
1973
2054
  ] }),
1974
- /* @__PURE__ */ jsxs25("dd", { children: [
2055
+ /* @__PURE__ */ jsxs26("dd", { children: [
1975
2056
  receipt.namedSeat.amountCents === 0 ? "Included \u2014 " : "",
1976
2057
  money(receipt.namedSeat.amountCents)
1977
2058
  ] })
1978
2059
  ] }) : null,
1979
- /* @__PURE__ */ jsx26("dt", { children: "Total paid" }),
1980
- /* @__PURE__ */ jsx26("dd", { children: money(receipt.totalCents) })
2060
+ /* @__PURE__ */ jsx27("dt", { children: "Total paid" }),
2061
+ /* @__PURE__ */ jsx27("dd", { children: money(receipt.totalCents) })
1981
2062
  ] }),
1982
- /* @__PURE__ */ jsxs25("div", { className: "journey-actions", children: [
1983
- /* @__PURE__ */ jsx26("a", { className: "apply-link journey-secondary", href: `${endpoint}&format=html`, target: "_blank", rel: "noopener noreferrer", children: "Print / save receipt" }),
1984
- /* @__PURE__ */ jsx26("button", { type: "button", disabled: emailState !== "idle", onClick: () => void email(), children: emailState === "sending" ? "Sending\u2026" : emailState === "sent" ? "Receipt emailed" : "Email me my receipt" })
2063
+ /* @__PURE__ */ jsxs26("div", { className: "journey-actions", children: [
2064
+ /* @__PURE__ */ jsx27("a", { className: "apply-link journey-secondary", href: `${endpoint}&format=html`, target: "_blank", rel: "noopener noreferrer", children: "Print / save receipt" }),
2065
+ /* @__PURE__ */ jsx27("button", { type: "button", disabled: emailState !== "idle", onClick: () => void email(), children: emailState === "sending" ? "Sending\u2026" : emailState === "sent" ? "Receipt emailed" : "Email me my receipt" })
1985
2066
  ] }),
1986
- emailState === "sent" ? /* @__PURE__ */ jsx26("p", { role: "status", children: previewEmail ? "Test receipt sent to the configured test inbox." : "Sent to the email used for your payment." }) : null,
1987
- error ? /* @__PURE__ */ jsx26("p", { role: "alert", children: error }) : null
2067
+ emailState === "sent" ? /* @__PURE__ */ jsx27("p", { role: "status", children: previewEmail ? "Test receipt sent to the configured test inbox." : "Sent to the email used for your payment." }) : null,
2068
+ error ? /* @__PURE__ */ jsx27("p", { role: "alert", children: error }) : null
1988
2069
  ] });
1989
2070
  }
1990
2071
 
1991
2072
  // src/ui/join.tsx
1992
- import { Fragment as Fragment10, jsx as jsx27, jsxs as jsxs26 } from "preact/jsx-runtime";
2073
+ import { Fragment as Fragment10, jsx as jsx28, jsxs as jsxs27 } from "preact/jsx-runtime";
1993
2074
  function JoinIsland(props) {
1994
- return /* @__PURE__ */ jsx27(JourneyFrame, { children: /* @__PURE__ */ jsx27(JoinFlow, { ...props }) });
2075
+ return /* @__PURE__ */ jsx28(JourneyFrame, { children: /* @__PURE__ */ jsx28(JoinFlow, { ...props }) });
1995
2076
  }
1996
2077
  function JoinFlow(props) {
1997
2078
  const inheritedCopy = useChapterCopy();
@@ -2012,14 +2093,15 @@ function JoinFlow(props) {
2012
2093
  const invitation = invitationState.invitation;
2013
2094
  const selectedTierId = invitation?.skuId ?? tierSelection.selectedTierId;
2014
2095
  const selectedTier = tiers.find((tier) => tier.id === selectedTierId) ?? tierSelection.selected;
2015
- const [state, setState] = useState20(requestedSeat ? { step: "form" } : props.initialState ?? { step: "form" });
2016
- const [error, setError] = useState20(null);
2017
- const [submitting, setSubmitting] = useState20(false);
2018
- const [editingNamedSeat, setEditingNamedSeat] = useState20(false);
2019
- const [giftOfferId, setGiftOfferId] = useState20(props.initialGiftOfferId ?? null);
2096
+ const [state, setState] = useState21(requestedSeat ? { step: "form" } : props.initialState ?? { step: "form" });
2097
+ const [error, setError] = useState21(null);
2098
+ const [submitting, setSubmitting] = useState21(false);
2099
+ const [editingNamedSeat, setEditingNamedSeat] = useState21(false);
2100
+ const [giftOfferId, setGiftOfferId] = useState21(props.initialGiftOfferId ?? null);
2020
2101
  const simulatedPayment = joinSimulationPayment(props.simulation, selectedTier?.priceCents ?? 0);
2021
2102
  const simulatedBooking = props.simulation ? props.simulation.booking ?? { slots: [], timezone: "UTC" } : void 0;
2022
- const submissionId = useRef7(null);
2103
+ const submissionId = useRef8(null);
2104
+ const slotsPreload = useJoinSlotsPreload(!props.simulation && ["payment", "paymentPending"].includes(state.step));
2023
2105
  useEffect11(() => {
2024
2106
  if (props.simulation) return;
2025
2107
  const resolver = requestedSeat ? () => invitation?.applicationId ? loadJoinResume(invitation.applicationId) : Promise.resolve(null) : props.loadResume ?? (() => {
@@ -2093,13 +2175,13 @@ function JoinFlow(props) {
2093
2175
  setSubmitting(false);
2094
2176
  }
2095
2177
  };
2096
- if (requestedSeat && !invitation) return /* @__PURE__ */ jsxs26("section", { className: "card", "aria-live": "polite", children: [
2097
- /* @__PURE__ */ jsx27("h2", { children: seatCopy.title }),
2098
- /* @__PURE__ */ jsx27("p", { role: invitationState.error ? "alert" : "status", children: invitationState.error || seatCopy.loading }),
2099
- invitationState.error ? /* @__PURE__ */ jsx27("button", { type: "button", onClick: invitationState.retry, children: seatCopy.retry }) : null
2178
+ if (requestedSeat && !invitation) return /* @__PURE__ */ jsxs27("section", { className: "card", "aria-live": "polite", children: [
2179
+ /* @__PURE__ */ jsx28("h2", { children: seatCopy.title }),
2180
+ /* @__PURE__ */ jsx28("p", { role: invitationState.error ? "alert" : "status", children: invitationState.error || seatCopy.loading }),
2181
+ invitationState.error ? /* @__PURE__ */ jsx28("button", { type: "button", onClick: invitationState.retry, children: seatCopy.retry }) : null
2100
2182
  ] });
2101
- const header = /* @__PURE__ */ jsxs26(Fragment10, { children: [
2102
- invitation ? /* @__PURE__ */ jsx27(
2183
+ const header = /* @__PURE__ */ jsxs27(Fragment10, { children: [
2184
+ invitation ? /* @__PURE__ */ jsx28(
2103
2185
  JoinInvitationNotice,
2104
2186
  {
2105
2187
  invitation,
@@ -2112,66 +2194,70 @@ function JoinFlow(props) {
2112
2194
  editingNamedSeat: state.step === "payment" && editingNamedSeat,
2113
2195
  ...invitation ? { invitation } : {},
2114
2196
  ..."applicationId" in state ? { applicationId: state.applicationId } : {}
2115
- }),
2116
- !props.simulation && !requestedSeat && ["paymentPending", "booking", "accepted", "done"].includes(state.step) && "applicationId" in state ? /* @__PURE__ */ jsx27(PaymentReceiptCard, { applicationId: state.applicationId }) : null
2197
+ })
2117
2198
  ] });
2199
+ const receipt = !props.simulation && !requestedSeat && ["paymentPending", "booking", "accepted", "done"].includes(state.step) && "applicationId" in state ? /* @__PURE__ */ jsx28(PaymentReceiptCard, { applicationId: state.applicationId }) : null;
2118
2200
  if (state.step === "closed") {
2119
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2201
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2120
2202
  header,
2121
- /* @__PURE__ */ jsxs26("section", { className: "card", "aria-label": "Application closed", children: [
2122
- /* @__PURE__ */ jsx27("h2", { children: "This application is closed" }),
2123
- /* @__PURE__ */ jsx27("p", { children: "This link cannot resume payment or booking. Sign in to view your application status, or contact the chapter if you need help." }),
2124
- /* @__PURE__ */ jsx27("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
2203
+ /* @__PURE__ */ jsxs27("section", { className: "card", "aria-label": "Application closed", children: [
2204
+ /* @__PURE__ */ jsx28("h2", { children: "This application is closed" }),
2205
+ /* @__PURE__ */ jsx28("p", { children: "This link cannot resume payment or booking. Sign in to view your application status, or contact the chapter if you need help." }),
2206
+ /* @__PURE__ */ jsx28("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
2125
2207
  ] })
2126
2208
  ] });
2127
2209
  }
2128
2210
  if (state.step === "done") {
2129
- const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs26("div", { className: "join-done card", children: [
2130
- /* @__PURE__ */ jsx27("div", { className: "card-label", children: copy.done.label }),
2131
- /* @__PURE__ */ jsx27("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
2132
- /* @__PURE__ */ jsx27("p", { className: "meeting-note", children: copy.done.calendarInvite }),
2133
- /* @__PURE__ */ jsx27("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
2211
+ const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs27("div", { className: "join-done card", children: [
2212
+ /* @__PURE__ */ jsx28("div", { className: "card-label", children: copy.done.label }),
2213
+ /* @__PURE__ */ jsx28("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
2214
+ /* @__PURE__ */ jsx28("p", { className: "meeting-note", children: copy.done.calendarInvite }),
2215
+ /* @__PURE__ */ jsx28("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
2134
2216
  ] });
2135
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2217
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2136
2218
  header,
2137
- body
2219
+ body,
2220
+ receipt
2138
2221
  ] });
2139
2222
  }
2140
2223
  if (state.step === "accepted") {
2141
- const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx27(JoinAccepted, { copy, membersHref });
2142
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2224
+ const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx28(JoinAccepted, { copy, membersHref });
2225
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2143
2226
  header,
2144
- body
2227
+ body,
2228
+ receipt
2145
2229
  ] });
2146
2230
  }
2147
2231
  if (state.step === "gift") {
2148
- const body = renderGift?.(state) ?? /* @__PURE__ */ jsx27(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
2149
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2232
+ const body = renderGift?.(state) ?? /* @__PURE__ */ jsx28(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
2233
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2150
2234
  header,
2151
2235
  body
2152
2236
  ] });
2153
2237
  }
2154
2238
  if (state.step === "booking") {
2155
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2239
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2156
2240
  header,
2157
- /* @__PURE__ */ jsx27(
2241
+ /* @__PURE__ */ jsx28(
2158
2242
  JoinBooking,
2159
2243
  {
2160
2244
  applicationId: state.applicationId,
2161
2245
  copy: copy.booking,
2162
2246
  simulation: simulatedBooking,
2247
+ preload: slotsPreload,
2163
2248
  onBooked: (booked) => {
2164
2249
  setState({ step: "done", applicationId: state.applicationId, booked });
2165
2250
  }
2166
2251
  }
2167
- )
2252
+ ),
2253
+ receipt
2168
2254
  ] });
2169
2255
  }
2170
2256
  if (state.step === "payment") {
2171
2257
  if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation && !state.giftPurchase) {
2172
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2258
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2173
2259
  header,
2174
- /* @__PURE__ */ jsx27(
2260
+ /* @__PURE__ */ jsx28(
2175
2261
  JoinNamedSeat,
2176
2262
  {
2177
2263
  api: props.namedSeatClaimApi,
@@ -2184,9 +2270,9 @@ function JoinFlow(props) {
2184
2270
  ] });
2185
2271
  }
2186
2272
  const Payment = state.giftPurchase || props.simulation ? PaymentStep : MembershipPaymentStep;
2187
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2273
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2188
2274
  header,
2189
- props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx27(
2275
+ props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx28(
2190
2276
  JoinGiftClaim,
2191
2277
  {
2192
2278
  api: props.giftClaimApi,
@@ -2197,7 +2283,7 @@ function JoinFlow(props) {
2197
2283
  onError: () => setError(copy.form.unexpectedFailure)
2198
2284
  }
2199
2285
  ) : null,
2200
- /* @__PURE__ */ jsx27(
2286
+ /* @__PURE__ */ jsx28(
2201
2287
  Payment,
2202
2288
  {
2203
2289
  applicationId: state.applicationId,
@@ -2225,9 +2311,9 @@ function JoinFlow(props) {
2225
2311
  }
2226
2312
  if (state.step === "paymentPending") {
2227
2313
  if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation) {
2228
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2314
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2229
2315
  header,
2230
- /* @__PURE__ */ jsx27(
2316
+ /* @__PURE__ */ jsx28(
2231
2317
  JoinNamedSeat,
2232
2318
  {
2233
2319
  api: props.namedSeatClaimApi,
@@ -2239,14 +2325,15 @@ function JoinFlow(props) {
2239
2325
  )
2240
2326
  ] });
2241
2327
  }
2242
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2328
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2243
2329
  header,
2244
- /* @__PURE__ */ jsx27("p", { className: "pay-status", role: "status", children: copy.payment.pending })
2330
+ /* @__PURE__ */ jsx28("p", { className: "pay-status", role: "status", children: copy.payment.pending }),
2331
+ receipt
2245
2332
  ] });
2246
2333
  }
2247
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2334
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2248
2335
  header,
2249
- /* @__PURE__ */ jsx27(
2336
+ /* @__PURE__ */ jsx28(
2250
2337
  JoinApplicationForm,
2251
2338
  {
2252
2339
  props,
@@ -2436,7 +2523,7 @@ function membershipPageDocument(input, options = {}) {
2436
2523
  }
2437
2524
 
2438
2525
  // src/ui/membership-cards.tsx
2439
- import { jsx as jsx28, jsxs as jsxs27 } from "preact/jsx-runtime";
2526
+ import { jsx as jsx29, jsxs as jsxs28 } from "preact/jsx-runtime";
2440
2527
  var MEMBERSHIP_CARD_TOKEN_DEFAULTS = Object.freeze({
2441
2528
  "--ui-membership-grid-gap": "1.4rem",
2442
2529
  "--ui-membership-card-padding": "2rem 1.7rem 1.8rem",
@@ -2505,67 +2592,67 @@ function membershipApplicationHref(applicationPath, tierId) {
2505
2592
  }
2506
2593
  function TierAction(props) {
2507
2594
  if (props.mode === "select") {
2508
- return /* @__PURE__ */ jsxs27("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
2595
+ return /* @__PURE__ */ jsxs28("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
2509
2596
  props.label,
2510
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192" })
2597
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: "\u2192" })
2511
2598
  ] });
2512
2599
  }
2513
2600
  if (props.mode === "preview") {
2514
- return /* @__PURE__ */ jsxs27("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
2601
+ return /* @__PURE__ */ jsxs28("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
2515
2602
  props.label,
2516
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192" })
2603
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: "\u2192" })
2517
2604
  ] });
2518
2605
  }
2519
- return /* @__PURE__ */ jsxs27("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
2606
+ return /* @__PURE__ */ jsxs28("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
2520
2607
  props.label,
2521
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192" })
2608
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: "\u2192" })
2522
2609
  ] });
2523
2610
  }
2524
2611
  function TierCard(props) {
2525
2612
  const { tier, presentation } = props;
2526
2613
  const summary = presentation.summaryMarkdown ?? tier.blurb;
2527
2614
  const action = presentation.ctaLabel ?? (tier.free ? "Join for free" : `Choose ${tier.name}`);
2528
- return /* @__PURE__ */ jsxs27("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
2529
- presentation.badge ? /* @__PURE__ */ jsx28("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
2530
- /* @__PURE__ */ jsx28("h3", { className: "chapter-membership-name", children: tier.name }),
2531
- /* @__PURE__ */ jsxs27("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
2532
- presentation.capacity ? /* @__PURE__ */ jsxs27("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
2533
- /* @__PURE__ */ jsx28("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
2534
- /* @__PURE__ */ jsx28("small", { children: presentation.capacity.label ?? "available" })
2615
+ return /* @__PURE__ */ jsxs28("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
2616
+ presentation.badge ? /* @__PURE__ */ jsx29("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
2617
+ /* @__PURE__ */ jsx29("h3", { className: "chapter-membership-name", children: tier.name }),
2618
+ /* @__PURE__ */ jsxs28("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
2619
+ presentation.capacity ? /* @__PURE__ */ jsxs28("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
2620
+ /* @__PURE__ */ jsx29("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
2621
+ /* @__PURE__ */ jsx29("small", { children: presentation.capacity.label ?? "available" })
2535
2622
  ] }) : null,
2536
- /* @__PURE__ */ jsxs27("div", { className: "chapter-membership-price-stack", children: [
2537
- presentation.priceEyebrow ? /* @__PURE__ */ jsx28("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : tier.founding ? /* @__PURE__ */ jsx28("p", { className: "chapter-membership-price-eyebrow", children: "Founding member rate" }) : null,
2538
- /* @__PURE__ */ jsxs27("div", { className: "chapter-membership-price-row", children: [
2539
- tier.founding ? /* @__PURE__ */ jsx28("span", { className: "chapter-membership-compare", children: fmtMoney(tier.priceCents) }) : presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx28("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
2540
- /* @__PURE__ */ jsx28("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.founding ? tier.founding.dueTodayCents : tier.priceCents) }),
2541
- !tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx28("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
2623
+ /* @__PURE__ */ jsxs28("div", { className: "chapter-membership-price-stack", children: [
2624
+ presentation.priceEyebrow ? /* @__PURE__ */ jsx29("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : tier.founding ? /* @__PURE__ */ jsx29("p", { className: "chapter-membership-price-eyebrow", children: "Founding member rate" }) : null,
2625
+ /* @__PURE__ */ jsxs28("div", { className: "chapter-membership-price-row", children: [
2626
+ tier.founding ? /* @__PURE__ */ jsx29("span", { className: "chapter-membership-compare", children: fmtMoney(tier.priceCents) }) : presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx29("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
2627
+ /* @__PURE__ */ jsx29("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.founding ? tier.founding.dueTodayCents : tier.priceCents) }),
2628
+ !tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx29("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
2542
2629
  ] })
2543
2630
  ] })
2544
2631
  ] }),
2545
- presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx28(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
2546
- summary ? /* @__PURE__ */ jsx28(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
2547
- presentation.benefits?.length ? /* @__PURE__ */ jsx28("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs27("li", { children: [
2548
- /* @__PURE__ */ jsx28("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
2549
- /* @__PURE__ */ jsx28(Markdown2, { className: "chapter-membership-benefit", source: benefit })
2632
+ presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx29(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
2633
+ summary ? /* @__PURE__ */ jsx29(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
2634
+ presentation.benefits?.length ? /* @__PURE__ */ jsx29("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs28("li", { children: [
2635
+ /* @__PURE__ */ jsx29("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
2636
+ /* @__PURE__ */ jsx29(Markdown2, { className: "chapter-membership-benefit", source: benefit })
2550
2637
  ] }, `${tier.id}-benefit-${index}`)) }) : null,
2551
- presentation.callout ? /* @__PURE__ */ jsxs27("aside", { className: "chapter-membership-callout", children: [
2552
- presentation.callout.label ? /* @__PURE__ */ jsx28("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
2553
- /* @__PURE__ */ jsx28(Markdown2, { source: presentation.callout.bodyMarkdown })
2638
+ presentation.callout ? /* @__PURE__ */ jsxs28("aside", { className: "chapter-membership-callout", children: [
2639
+ presentation.callout.label ? /* @__PURE__ */ jsx29("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
2640
+ /* @__PURE__ */ jsx29(Markdown2, { source: presentation.callout.bodyMarkdown })
2554
2641
  ] }) : null,
2555
- /* @__PURE__ */ jsx28(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
2642
+ /* @__PURE__ */ jsx29(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
2556
2643
  ] });
2557
2644
  }
2558
2645
  function MembershipCards(props) {
2559
2646
  const document2 = membershipPageDocument(props.document, { tiers: props.tiers });
2560
2647
  const byId = new Map(props.tiers.map((tier) => [tier.id, tier]));
2561
2648
  const mode = props.mode ?? "link";
2562
- return /* @__PURE__ */ jsxs27("section", { className: ["chapter-membership", props.className].filter(Boolean).join(" "), "data-chapter-membership": MEMBERSHIP_PAGE_RENDERER, "aria-label": props.ariaLabel ?? "Membership options", children: [
2563
- /* @__PURE__ */ jsx28("style", { children: MEMBERSHIP_CARDS_CSS }),
2564
- /* @__PURE__ */ jsx28("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
2649
+ return /* @__PURE__ */ jsxs28("section", { className: ["chapter-membership", props.className].filter(Boolean).join(" "), "data-chapter-membership": MEMBERSHIP_PAGE_RENDERER, "aria-label": props.ariaLabel ?? "Membership options", children: [
2650
+ /* @__PURE__ */ jsx29("style", { children: MEMBERSHIP_CARDS_CSS }),
2651
+ /* @__PURE__ */ jsx29("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
2565
2652
  const tier = byId.get(presentation.tierId);
2566
- return /* @__PURE__ */ jsx28(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
2653
+ return /* @__PURE__ */ jsx29(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
2567
2654
  }) }),
2568
- document2.footnoteMarkdown ? /* @__PURE__ */ jsx28(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
2655
+ document2.footnoteMarkdown ? /* @__PURE__ */ jsx29(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
2569
2656
  ] });
2570
2657
  }
2571
2658
 
@@ -2591,6 +2678,10 @@ export {
2591
2678
  GiftOfferCards,
2592
2679
  GiftPurchases,
2593
2680
  MemberGifts,
2681
+ namedSeatInvitationShareable,
2682
+ namedSeatInvitationUrl,
2683
+ namedSeatInvitationMessage,
2684
+ NamedSeatInvitationLink,
2594
2685
  NAMED_SEAT_RECIPIENT_WORDS,
2595
2686
  NamedSeatRecipientLine,
2596
2687
  NamedSeatPurchase,
@@ -2606,4 +2697,4 @@ export {
2606
2697
  membershipApplicationHref,
2607
2698
  MembershipCards
2608
2699
  };
2609
- //# sourceMappingURL=chunk-CKC6X5H2.js.map
2700
+ //# sourceMappingURL=chunk-Y2H4VURI.js.map