@odla-ai/chapter 0.58.1 → 0.59.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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",
@@ -1044,12 +1104,13 @@ var NAMED_SEAT_RECIPIENT_WORDS = {
1044
1104
  joined: "joined as a member",
1045
1105
  declined: "declined the seat",
1046
1106
  refunded: "seat refunded",
1047
- canceled: "seat canceled"
1107
+ canceled: "seat canceled",
1108
+ disputed: "seat payment disputed with the card issuer; their access is paused until it is resolved"
1048
1109
  };
1049
1110
  var day = (at) => new Date(at).toLocaleDateString("en-US", { timeZone: "UTC" });
1050
1111
  function NamedSeatRecipientLine({ seat }) {
1051
1112
  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: [
1113
+ return /* @__PURE__ */ jsxs14("p", { className: "member-named-seat-recipient", children: [
1053
1114
  seat.recipientName,
1054
1115
  " \xB7 ",
1055
1116
  seat.recipientEmail,
@@ -1059,10 +1120,10 @@ function NamedSeatRecipientLine({ seat }) {
1059
1120
  ] });
1060
1121
  }
1061
1122
  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("");
1123
+ const [data, setData] = useState11(null), [error, setError] = useState11("");
1124
+ const [name, setName] = useState11(""), [email, setEmail] = useState11(""), [reviewing, setReviewing] = useState11(false);
1125
+ const [terms, setTerms] = useState11(false), [pending, setPending] = useState11(false), [granting, setGranting] = useState11(false);
1126
+ const [renaming, setRenaming] = useState11(false), [nextName, setNextName] = useState11(""), [nextEmail, setNextEmail] = useState11("");
1066
1127
  const load = async () => {
1067
1128
  try {
1068
1129
  const value = await api("/api/named-seat");
@@ -1117,38 +1178,41 @@ function NamedSeatPurchase({ api }) {
1117
1178
  setGranting(false);
1118
1179
  }
1119
1180
  };
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: () => {
1181
+ return /* @__PURE__ */ jsx15(JourneyFrame, { children: /* @__PURE__ */ jsxs14("section", { className: "card member-named-seat", "aria-label": "Named additional seat", children: [
1182
+ /* @__PURE__ */ jsx15("h2", { children: "Named additional seat" }),
1183
+ error ? /* @__PURE__ */ jsx15("p", { role: "alert", children: error }) : null,
1184
+ data ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
1185
+ data.seat ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
1186
+ /* @__PURE__ */ jsx15(NamedSeatRecipientLine, { seat: data.seat }),
1187
+ /* @__PURE__ */ jsx15(NamedSeatInvitationLink, { seat: data.seat })
1188
+ ] }) : null,
1189
+ data.seat?.regiftable && !renaming ? /* @__PURE__ */ jsx15("button", { className: "btn secondary", type: "button", onClick: () => {
1126
1190
  setRenaming(true);
1127
1191
  setNextName("");
1128
1192
  setNextEmail("");
1129
1193
  }, 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: [
1194
+ 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: [
1195
+ /* @__PURE__ */ jsxs14("p", { children: [
1132
1196
  "The seat moves to the person you name here. ",
1133
1197
  data.seat.recipientName,
1134
1198
  "'s invitation stops working, and nothing is charged or refunded."
1135
1199
  ] }),
1136
- /* @__PURE__ */ jsxs13("label", { children: [
1200
+ /* @__PURE__ */ jsxs14("label", { children: [
1137
1201
  "New recipient name",
1138
- /* @__PURE__ */ jsx14("input", { required: true, maxLength: 160, value: nextName, onInput: (event) => setNextName(event.currentTarget.value) })
1202
+ /* @__PURE__ */ jsx15("input", { required: true, maxLength: 160, value: nextName, onInput: (event) => setNextName(event.currentTarget.value) })
1139
1203
  ] }),
1140
- /* @__PURE__ */ jsxs13("label", { children: [
1204
+ /* @__PURE__ */ jsxs14("label", { children: [
1141
1205
  "New recipient email",
1142
- /* @__PURE__ */ jsx14("input", { required: true, type: "email", maxLength: 254, value: nextEmail, onInput: (event) => setNextEmail(event.currentTarget.value) })
1206
+ /* @__PURE__ */ jsx15("input", { required: true, type: "email", maxLength: 254, value: nextEmail, onInput: (event) => setNextEmail(event.currentTarget.value) })
1143
1207
  ] }),
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: [
1208
+ /* @__PURE__ */ jsx15("button", { className: "btn primary", type: "submit", disabled: granting, children: granting ? "Changing the recipient\u2026" : "Give the seat to this person" }),
1209
+ /* @__PURE__ */ jsxs14("button", { className: "btn secondary", type: "button", disabled: granting, onClick: () => setRenaming(false), children: [
1146
1210
  "Keep ",
1147
1211
  data.seat.recipientName
1148
1212
  ] })
1149
1213
  ] }) : null,
1150
- data.eligible ? /* @__PURE__ */ jsxs13(Fragment3, { children: [
1151
- /* @__PURE__ */ jsxs13("p", { children: [
1214
+ data.eligible ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
1215
+ /* @__PURE__ */ jsxs14("p", { children: [
1152
1216
  data.included ? "Included with your membership at no charge." : `${money} paid in full now.`,
1153
1217
  " This seat ",
1154
1218
  data.autoRenew ? "renews with your primary membership" : "ends with your primary membership",
@@ -1159,39 +1223,39 @@ function NamedSeatPurchase({ api }) {
1159
1223
  " ",
1160
1224
  "It belongs to one named person and cannot be reassigned."
1161
1225
  ] }),
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) => {
1226
+ /* @__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." }),
1227
+ !reviewing ? /* @__PURE__ */ jsxs14("form", { onSubmit: (event) => {
1164
1228
  event.preventDefault();
1165
1229
  setReviewing(true);
1166
1230
  setTerms(false);
1167
1231
  }, children: [
1168
- /* @__PURE__ */ jsxs13("label", { children: [
1232
+ /* @__PURE__ */ jsxs14("label", { children: [
1169
1233
  "Recipient name",
1170
- /* @__PURE__ */ jsx14("input", { required: true, maxLength: 160, value: name, disabled: Boolean(data.seat), onInput: (event) => setName(event.currentTarget.value) })
1234
+ /* @__PURE__ */ jsx15("input", { required: true, maxLength: 160, value: name, disabled: Boolean(data.seat), onInput: (event) => setName(event.currentTarget.value) })
1171
1235
  ] }),
1172
- /* @__PURE__ */ jsxs13("label", { children: [
1236
+ /* @__PURE__ */ jsxs14("label", { children: [
1173
1237
  "Recipient email",
1174
- /* @__PURE__ */ jsx14("input", { required: true, type: "email", maxLength: 254, value: email, disabled: Boolean(data.seat), onInput: (event) => setEmail(event.currentTarget.value) })
1238
+ /* @__PURE__ */ jsx15("input", { required: true, type: "email", maxLength: 254, value: email, disabled: Boolean(data.seat), onInput: (event) => setEmail(event.currentTarget.value) })
1175
1239
  ] }),
1176
- /* @__PURE__ */ jsx14("button", { className: "btn primary", type: "submit", children: "Review named seat" })
1177
- ] }) : /* @__PURE__ */ jsxs13(Fragment3, { children: [
1178
- /* @__PURE__ */ jsxs13("p", { children: [
1240
+ /* @__PURE__ */ jsx15("button", { className: "btn primary", type: "submit", children: "Review named seat" })
1241
+ ] }) : /* @__PURE__ */ jsxs14(Fragment3, { children: [
1242
+ /* @__PURE__ */ jsxs14("p", { children: [
1179
1243
  "For ",
1180
1244
  name,
1181
1245
  " \xB7 ",
1182
1246
  email
1183
1247
  ] }),
1184
- /* @__PURE__ */ jsx14("button", { className: "btn secondary", type: "button", onClick: () => {
1248
+ /* @__PURE__ */ jsx15("button", { className: "btn secondary", type: "button", onClick: () => {
1185
1249
  setReviewing(false);
1186
1250
  setTerms(false);
1187
1251
  void load();
1188
1252
  }, 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." })
1253
+ /* @__PURE__ */ jsxs14("label", { className: "journey-consent", children: [
1254
+ /* @__PURE__ */ jsx15("input", { type: "checkbox", checked: terms, onChange: (event) => setTerms(event.currentTarget.checked) }),
1255
+ /* @__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
1256
  ] }),
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(
1257
+ 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,
1258
+ terms && !data.included ? /* @__PURE__ */ jsx15(
1195
1259
  PaymentStep,
1196
1260
  {
1197
1261
  applicationId: data.membershipId,
@@ -1206,17 +1270,17 @@ function NamedSeatPurchase({ api }) {
1206
1270
  }
1207
1271
  ) : null
1208
1272
  ] })
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" })
1273
+ ] }) : !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,
1274
+ 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
1275
+ ] }) : !error ? /* @__PURE__ */ jsx15("p", { children: "Loading your seat terms\u2026" }) : null,
1276
+ /* @__PURE__ */ jsx15("button", { className: "btn secondary", onClick: () => void load(), children: "Refresh seat status" })
1213
1277
  ] }) });
1214
1278
  }
1215
1279
 
1216
1280
  // src/ui/member-content.tsx
1217
- import { useEffect as useEffect5, useMemo as useMemo2, useState as useState11 } from "preact/hooks";
1281
+ import { useEffect as useEffect5, useMemo as useMemo2, useState as useState12 } from "preact/hooks";
1218
1282
  import { Markdown } from "@odla-ai/ui/components";
1219
- import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs14 } from "preact/jsx-runtime";
1283
+ import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs15 } from "preact/jsx-runtime";
1220
1284
  var pageLabel = (page) => `${page.title}${page.access === "locked" ? " \xB7 Locked" : ""}`;
1221
1285
  function MemberContentArea(props) {
1222
1286
  const {
@@ -1224,12 +1288,12 @@ function MemberContentArea(props) {
1224
1288
  path = "/api/member-content",
1225
1289
  upsellHref,
1226
1290
  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." })
1291
+ loadingContent = /* @__PURE__ */ jsx16("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
1292
+ emptyContent = /* @__PURE__ */ jsx16("p", { className: "meeting-note", children: "No member pages have been published yet." })
1229
1293
  } = props;
1230
- const [data, setData] = useState11(props.initialData ?? null);
1231
- const [error, setError] = useState11(null);
1232
- const [selectedId, setSelectedId] = useState11(
1294
+ const [data, setData] = useState12(props.initialData ?? null);
1295
+ const [error, setError] = useState12(null);
1296
+ const [selectedId, setSelectedId] = useState12(
1233
1297
  props.initialPageId ?? props.initialData?.pages[0]?.id ?? ""
1234
1298
  );
1235
1299
  useEffect5(() => {
@@ -1254,18 +1318,18 @@ function MemberContentArea(props) {
1254
1318
  }
1255
1319
  return [...result.entries()];
1256
1320
  }, [data]);
1257
- if (error) return /* @__PURE__ */ jsxs14("p", { className: "meeting-note", role: "alert", children: [
1321
+ if (error) return /* @__PURE__ */ jsxs15("p", { className: "meeting-note", role: "alert", children: [
1258
1322
  "Member pages could not be loaded: ",
1259
1323
  error
1260
1324
  ] });
1261
- if (!data) return /* @__PURE__ */ jsx15(Fragment4, { children: loadingContent });
1262
- if (data.pages.length === 0) return /* @__PURE__ */ jsx15(Fragment4, { children: emptyContent });
1325
+ if (!data) return /* @__PURE__ */ jsx16(Fragment4, { children: loadingContent });
1326
+ if (data.pages.length === 0) return /* @__PURE__ */ jsx16(Fragment4, { children: emptyContent });
1263
1327
  const selected = data.pages.find((page) => page.id === selectedId) ?? data.pages[0];
1264
1328
  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(
1329
+ return /* @__PURE__ */ jsxs15("div", { className: "chapter-member-content", "data-member-content": true, children: [
1330
+ /* @__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: [
1331
+ /* @__PURE__ */ jsx16("h2", { children: section }),
1332
+ /* @__PURE__ */ jsx16("ul", { children: pages.map((page) => /* @__PURE__ */ jsx16("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx16(
1269
1333
  "button",
1270
1334
  {
1271
1335
  type: "button",
@@ -1275,23 +1339,23 @@ function MemberContentArea(props) {
1275
1339
  }
1276
1340
  ) }, page.id)) })
1277
1341
  ] }, 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: [
1342
+ /* @__PURE__ */ jsxs15("article", { className: "chapter-member-content-page", "data-access": selected.access, children: [
1343
+ /* @__PURE__ */ jsxs15("header", { children: [
1344
+ /* @__PURE__ */ jsxs15("div", { className: "card-label", children: [
1281
1345
  selected.source.type === "parent" ? "Parent" : "Chapter",
1282
1346
  " \xB7 ",
1283
1347
  selected.access
1284
1348
  ] }),
1285
- /* @__PURE__ */ jsx15("h1", { children: selected.title }),
1286
- selected.summary ? /* @__PURE__ */ jsx15("p", { children: selected.summary }) : null
1349
+ /* @__PURE__ */ jsx16("h1", { children: selected.title }),
1350
+ selected.summary ? /* @__PURE__ */ jsx16("p", { children: selected.summary }) : null
1287
1351
  ] }),
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
1352
+ selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx16(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs15("div", { className: "chapter-member-content-locked", children: [
1353
+ selected.teaserMarkdown ? /* @__PURE__ */ jsx16(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx16("p", { children: "This page is not included in your current membership." }),
1354
+ selected.upsell ? /* @__PURE__ */ jsxs15("aside", { className: "chapter-member-content-upsell", "aria-label": selected.upsell.label ?? "Membership option", children: [
1355
+ /* @__PURE__ */ jsx16("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
1356
+ /* @__PURE__ */ jsx16("p", { children: fmtMoney(selected.upsell.priceCents) }),
1357
+ selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx16(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
1358
+ 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
1359
  ] }) : null
1296
1360
  ] })
1297
1361
  ] })
@@ -1299,12 +1363,12 @@ function MemberContentArea(props) {
1299
1363
  }
1300
1364
 
1301
1365
  // src/ui/members.tsx
1302
- import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs15 } from "preact/jsx-runtime";
1366
+ import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs16 } from "preact/jsx-runtime";
1303
1367
  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 }),
1368
+ return /* @__PURE__ */ jsxs16("div", { className: "card", children: [
1369
+ /* @__PURE__ */ jsx17("div", { className: "card-label", children: copy.provisional.cardLabel }),
1370
+ /* @__PURE__ */ jsxs16("div", { className: "meeting-block", children: [
1371
+ /* @__PURE__ */ jsx17("div", { className: "meeting-kicker", children: kicker }),
1308
1372
  body
1309
1373
  ] })
1310
1374
  ] });
@@ -1315,9 +1379,9 @@ function ProvisionalCard(props) {
1315
1379
  return card(
1316
1380
  copy,
1317
1381
  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 })
1382
+ /* @__PURE__ */ jsxs16(Fragment5, { children: [
1383
+ /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
1384
+ /* @__PURE__ */ jsx17("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
1321
1385
  ] })
1322
1386
  );
1323
1387
  }
@@ -1325,19 +1389,19 @@ function ProvisionalCard(props) {
1325
1389
  return card(
1326
1390
  copy,
1327
1391
  copy.provisional.refunded,
1328
- /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.refundedBody })
1392
+ /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: copy.provisional.refundedBody })
1329
1393
  );
1330
1394
  }
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;
1395
+ 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
1396
  if (application.meetingAt) {
1333
1397
  return card(
1334
1398
  copy,
1335
1399
  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(
1400
+ /* @__PURE__ */ jsxs16(Fragment5, { children: [
1401
+ /* @__PURE__ */ jsx17("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
1402
+ /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
1403
+ application.meetUrl ? /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: /* @__PURE__ */ jsx17("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
1404
+ /* @__PURE__ */ jsx17(
1341
1405
  Rescheduler,
1342
1406
  {
1343
1407
  api,
@@ -1354,9 +1418,9 @@ function ProvisionalCard(props) {
1354
1418
  return card(
1355
1419
  copy,
1356
1420
  copy.provisional.bookCall,
1357
- /* @__PURE__ */ jsxs15(Fragment5, { children: [
1358
- /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
1359
- /* @__PURE__ */ jsx16(
1421
+ /* @__PURE__ */ jsxs16(Fragment5, { children: [
1422
+ /* @__PURE__ */ jsx17("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
1423
+ /* @__PURE__ */ jsx17(
1360
1424
  Rescheduler,
1361
1425
  {
1362
1426
  api,
@@ -1383,8 +1447,8 @@ function MembersArea(props) {
1383
1447
  renderProvisional
1384
1448
  } = props;
1385
1449
  const copy = props.copy ?? inheritedCopy.members;
1386
- const [me, setMe] = useState12(null);
1387
- const [error, setError] = useState12(false);
1450
+ const [me, setMe] = useState13(null);
1451
+ const [error, setError] = useState13(false);
1388
1452
  const reload = async () => {
1389
1453
  try {
1390
1454
  setMe(await api("/api/me"));
@@ -1395,22 +1459,22 @@ function MembersArea(props) {
1395
1459
  useEffect6(() => {
1396
1460
  void reload();
1397
1461
  }, []);
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 });
1462
+ if (error) return /* @__PURE__ */ jsx17("p", { className: "meeting-note", children: copy.loadFailed });
1463
+ if (!me) return /* @__PURE__ */ jsx17("p", { className: "meeting-note", children: inheritedCopy.common.loading });
1400
1464
  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 })
1465
+ return /* @__PURE__ */ jsxs16(Fragment5, { children: [
1466
+ /* @__PURE__ */ jsxs16("div", { className: "card", children: [
1467
+ /* @__PURE__ */ jsxs16("div", { className: "member-row", children: [
1468
+ /* @__PURE__ */ jsx17("span", { className: "member-email", children: me.email }),
1469
+ /* @__PURE__ */ jsx17("span", { className: "role-badge " + role, children: role })
1406
1470
  ] }),
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
1471
+ /* @__PURE__ */ jsxs16("div", { className: "account-actions", children: [
1472
+ /* @__PURE__ */ jsx17("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
1473
+ me.authorized || me.superAdmin ? /* @__PURE__ */ jsx17("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
1410
1474
  ] })
1411
1475
  ] }),
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(
1476
+ me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */ jsx17(MemberRestart, { api, application: me.application, applicationId: me.membershipRestart.applicationId, onComplete: reload }) : me.memberAccess !== true ? (() => {
1477
+ const defaultContent = /* @__PURE__ */ jsx17(
1414
1478
  ProvisionalCard,
1415
1479
  {
1416
1480
  api,
@@ -1427,31 +1491,43 @@ function MembersArea(props) {
1427
1491
  reload,
1428
1492
  defaultContent
1429
1493
  }) ?? defaultContent;
1430
- })() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx16(
1494
+ })() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx17(
1431
1495
  MemberContentArea,
1432
1496
  {
1433
1497
  api,
1434
1498
  ...memberPages === true ? {} : memberPages
1435
1499
  }
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
1500
+ ) : /* @__PURE__ */ jsx17("div", { className: "card", children: /* @__PURE__ */ jsx17("div", { className: "card-label", children: copy.full.welcome }) })),
1501
+ /* @__PURE__ */ jsx17(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment }),
1502
+ me.namedSeatsEnabled ? /* @__PURE__ */ jsx17(NamedSeatPurchase, { api }) : null
1439
1503
  ] });
1440
1504
  }
1441
1505
 
1442
1506
  // src/ui/join.tsx
1443
- import { useEffect as useEffect11, useRef as useRef7, useState as useState20 } from "preact/hooks";
1507
+ import { useEffect as useEffect11, useRef as useRef8, useState as useState21 } from "preact/hooks";
1444
1508
 
1445
1509
  // 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";
1510
+ import { useEffect as useEffect7, useRef as useRef6, useState as useState14 } from "preact/hooks";
1511
+ import { jsx as jsx18, jsxs as jsxs17 } from "preact/jsx-runtime";
1512
+ function useJoinSlotsPreload(active) {
1513
+ const preload = useRef6(null);
1514
+ useEffect7(() => {
1515
+ if (!active || preload.current) return;
1516
+ preload.current = Promise.resolve().then(() => fetch("/api/schedule/slots"));
1517
+ preload.current.catch(() => {
1518
+ preload.current = null;
1519
+ });
1520
+ }, [active]);
1521
+ return preload.current ?? void 0;
1522
+ }
1448
1523
  function JoinBooking(props) {
1449
1524
  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 () => {
1525
+ const [state, setState] = useState14(null);
1526
+ const [msg, setMsg] = useState14(null);
1527
+ const [busy, setBusy] = useState14(false);
1528
+ const [day2, setDay] = useState14(null);
1529
+ const [selected, setSelected] = useState14(null);
1530
+ const load = async (preloaded) => {
1455
1531
  setMsg(null);
1456
1532
  try {
1457
1533
  if (simulation) {
@@ -1463,7 +1539,7 @@ function JoinBooking(props) {
1463
1539
  setState({ slots: [...simulation.slots], timezone: simulation.timezone });
1464
1540
  return;
1465
1541
  }
1466
- const res = await fetch("/api/schedule/slots");
1542
+ const res = await (preloaded ?? fetch("/api/schedule/slots"));
1467
1543
  const data = await res.json();
1468
1544
  if (data.schedulingReady === false || !data.slots?.length) {
1469
1545
  setState(null);
@@ -1476,7 +1552,7 @@ function JoinBooking(props) {
1476
1552
  }
1477
1553
  };
1478
1554
  useEffect7(() => {
1479
- void load();
1555
+ void load(props.preload);
1480
1556
  }, [simulation]);
1481
1557
  const book = async () => {
1482
1558
  if (!selected) return;
@@ -1507,43 +1583,49 @@ function JoinBooking(props) {
1507
1583
  setBusy(false);
1508
1584
  }
1509
1585
  };
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(
1586
+ if (!state) return /* @__PURE__ */ jsx18("p", { className: "slots-status", children: msg ?? copy.loading });
1587
+ const hint = !day2 ? copy.pickDate ?? DEFAULT_JOIN_COPY.booking.pickDate : !selected ? copy.pickTime ?? DEFAULT_JOIN_COPY.booking.pickTime : null;
1588
+ return /* @__PURE__ */ jsxs17("div", { className: "join-book", children: [
1589
+ /* @__PURE__ */ jsx18("h2", { children: copy.title ?? DEFAULT_JOIN_COPY.booking.title }),
1590
+ /* @__PURE__ */ jsx18("p", { children: copy.intro ?? DEFAULT_JOIN_COPY.booking.intro }),
1591
+ /* @__PURE__ */ jsxs17("div", { className: "slot-confirm", children: [
1592
+ /* @__PURE__ */ jsx18("button", { className: "submit-btn", type: "button", disabled: busy || !selected, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
1593
+ hint ? /* @__PURE__ */ jsx18("p", { className: "slot-hint", role: "status", children: hint }) : null,
1594
+ msg ? /* @__PURE__ */ jsx18("p", { className: "step2-note", role: "alert", children: msg }) : null
1595
+ ] }),
1596
+ /* @__PURE__ */ jsx18(
1515
1597
  SlotPicker,
1516
1598
  {
1517
1599
  slots: state.slots,
1518
1600
  timezone: state.timezone,
1519
1601
  selectedStartAt: selected?.startAt,
1520
1602
  onPick: setSelected,
1521
- onDayChange: () => setSelected(null)
1603
+ initialDay: "none",
1604
+ onDayChange: (key) => {
1605
+ setDay(key);
1606
+ setSelected(null);
1607
+ }
1522
1608
  }
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
- ] })
1609
+ )
1528
1610
  ] });
1529
1611
  }
1530
1612
 
1531
1613
  // src/ui/join-accepted.tsx
1532
- import { jsx as jsx18, jsxs as jsxs17 } from "preact/jsx-runtime";
1614
+ import { jsx as jsx19, jsxs as jsxs18 } from "preact/jsx-runtime";
1533
1615
  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 })
1616
+ return /* @__PURE__ */ jsxs18("div", { className: "join-done card", children: [
1617
+ /* @__PURE__ */ jsx19("div", { className: "card-label", children: props.copy.accepted.label }),
1618
+ /* @__PURE__ */ jsx19("p", { className: "meeting-note", children: props.copy.accepted.body }),
1619
+ /* @__PURE__ */ jsx19("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
1538
1620
  ] });
1539
1621
  }
1540
1622
 
1541
1623
  // 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";
1624
+ import { useState as useState15 } from "preact/hooks";
1625
+ import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs19 } from "preact/jsx-runtime";
1544
1626
  function GiftClaimCard(props) {
1545
- const [code, setCode] = useState14(props.initialCode ?? "");
1546
- const [error, setError] = useState14(false);
1627
+ const [code, setCode] = useState15(props.initialCode ?? "");
1628
+ const [error, setError] = useState15(false);
1547
1629
  const rotate = async () => {
1548
1630
  if (!props.claimId) return;
1549
1631
  setError(false);
@@ -1556,27 +1638,27 @@ function GiftClaimCard(props) {
1556
1638
  if (response.ok && body.code) setCode(body.code);
1557
1639
  else setError(true);
1558
1640
  };
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 })
1641
+ return /* @__PURE__ */ jsxs19("div", { className: "join-done card", children: [
1642
+ /* @__PURE__ */ jsx20("div", { className: "card-label", children: props.copy.label }),
1643
+ /* @__PURE__ */ jsx20("p", { className: "meeting-note", children: props.copy.body }),
1644
+ code ? /* @__PURE__ */ jsxs19(Fragment6, { children: [
1645
+ /* @__PURE__ */ jsx20("output", { className: "gift-code", children: code }),
1646
+ /* @__PURE__ */ jsx20("p", { children: props.copy.save })
1565
1647
  ] }) : 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
1648
+ !code && props.claimId ? /* @__PURE__ */ jsx20("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
1649
+ error ? /* @__PURE__ */ jsx20("p", { role: "alert", children: props.copy.rotateFailed }) : null
1568
1650
  ] });
1569
1651
  }
1570
1652
 
1571
1653
  // src/ui/join-application-form.tsx
1572
- import { useRef as useRef6 } from "preact/hooks";
1654
+ import { useRef as useRef7 } from "preact/hooks";
1573
1655
 
1574
1656
  // 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";
1657
+ import { useState as useState16 } from "preact/hooks";
1658
+ import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs20 } from "preact/jsx-runtime";
1577
1659
  var joinTierMoney = (cents, currency = "usd") => new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
1578
1660
  function useTierSelection(tiers, initialTierId) {
1579
- const [selectedTierId, setSelectedTierId] = useState15(() => {
1661
+ const [selectedTierId, setSelectedTierId] = useState16(() => {
1580
1662
  const preset = tiers.find((tier) => tier.id === initialTierId);
1581
1663
  if (preset) return preset.id;
1582
1664
  return tiers.length === 1 ? tiers[0].id : null;
@@ -1591,10 +1673,10 @@ function useTierSelection(tiers, initialTierId) {
1591
1673
  };
1592
1674
  }
1593
1675
  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(
1676
+ return /* @__PURE__ */ jsxs20("fieldset", { "data-chapter-placeholder": "tiers", children: [
1677
+ /* @__PURE__ */ jsx21("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
1678
+ context.tiers.map((tier) => /* @__PURE__ */ jsxs20("label", { children: [
1679
+ /* @__PURE__ */ jsx21(
1598
1680
  "input",
1599
1681
  {
1600
1682
  type: "radio",
@@ -1605,13 +1687,13 @@ function TierPlaceholder(context) {
1605
1687
  }
1606
1688
  ),
1607
1689
  tier.name,
1608
- tier.founding ? /* @__PURE__ */ jsxs19(Fragment7, { children: [
1690
+ tier.founding ? /* @__PURE__ */ jsxs20(Fragment7, { children: [
1609
1691
  " \u2014 ",
1610
1692
  joinTierMoney(tier.founding.dueTodayCents),
1611
1693
  " founding member rate (list ",
1612
1694
  joinTierMoney(tier.priceCents),
1613
1695
  ")"
1614
- ] }) : tier.free ? " \u2014 free" : /* @__PURE__ */ jsxs19(Fragment7, { children: [
1696
+ ] }) : tier.free ? " \u2014 free" : /* @__PURE__ */ jsxs20(Fragment7, { children: [
1615
1697
  " \u2014 ",
1616
1698
  joinTierMoney(tier.priceCents)
1617
1699
  ] })
@@ -1623,12 +1705,12 @@ function tierNeedsPayment(selected, paymentsReady) {
1623
1705
  }
1624
1706
 
1625
1707
  // src/ui/join-application-form.tsx
1626
- import { jsx as jsx21, jsxs as jsxs20 } from "preact/jsx-runtime";
1708
+ import { jsx as jsx22, jsxs as jsxs21 } from "preact/jsx-runtime";
1627
1709
  function JoinApplicationForm({ props, copy, invitation, requestedSeat, tierSelection, giftOfferId, selectGift, submitting, error, submit }) {
1628
- const form = useRef6(null);
1710
+ const form = useRef7(null);
1629
1711
  const ready = useFormReadiness(form);
1630
1712
  const disabled = submitting || props.submitDisabled === true || !ready || !validJoinRecipient(props.payment?.initialNamedSeat);
1631
- return /* @__PURE__ */ jsxs20("form", { ref: form, className: "join-form", onSubmit: (event) => {
1713
+ return /* @__PURE__ */ jsxs21("form", { ref: form, className: "join-form", onSubmit: (event) => {
1632
1714
  if (!isFormReady(event.currentTarget)) {
1633
1715
  event.preventDefault();
1634
1716
  event.currentTarget.reportValidity();
@@ -1636,15 +1718,15 @@ function JoinApplicationForm({ props, copy, invitation, requestedSeat, tierSelec
1636
1718
  }
1637
1719
  void submit(event);
1638
1720
  }, 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 })
1721
+ !requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs21("fieldset", { children: [
1722
+ /* @__PURE__ */ jsx22("legend", { children: copy.gift.optionsLabel }),
1723
+ /* @__PURE__ */ jsx22("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => selectGift(null), children: copy.gift.chooseSelf }),
1724
+ /* @__PURE__ */ jsx22(GiftOfferCards, { offers: props.config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: selectGift })
1643
1725
  ] }) : null,
1644
1726
  !requestedSeat && (props.config.tiers?.length ?? 0) > 1 ? props.renderTiers?.(tierSelection) ?? TierPlaceholder(tierSelection) : null,
1645
1727
  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 })
1728
+ error ? /* @__PURE__ */ jsx22("p", { className: "join-error", role: "alert", children: error }) : null,
1729
+ props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */ jsx22(JoinSubmitButton, { disabled, children: submitting ? copy.form.submitting : copy.form.submit })
1648
1730
  ] });
1649
1731
  }
1650
1732
 
@@ -1669,8 +1751,8 @@ function joinStateFromApplicationResponse(data, fallbackNeedsPayment, submittedG
1669
1751
 
1670
1752
  // src/ui/gift-code-redeemer.tsx
1671
1753
  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";
1754
+ import { useState as useState17 } from "preact/hooks";
1755
+ import { Fragment as Fragment8, jsx as jsx23, jsxs as jsxs22 } from "preact/jsx-runtime";
1674
1756
  var GIFT_CODE_REDEEMER_CSS = `
1675
1757
  .gift-code-redeemer{container-type:inline-size;display:grid;gap:var(--ui-space-1,.35rem);margin:0}
1676
1758
  .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 +1767,10 @@ var GIFT_CODE_REDEEMER_CSS = `
1685
1767
  @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
1768
  `;
1687
1769
  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");
1770
+ const [code, setCode] = useState17("");
1771
+ const [loading, setLoading] = useState17(false);
1772
+ const [message, setMessage] = useState17("");
1773
+ const [messageTone, setMessageTone] = useState17("neutral");
1692
1774
  const normalizedCode = code.trim();
1693
1775
  const redeem = async () => {
1694
1776
  if (!normalizedCode || loading) return;
@@ -1715,9 +1797,9 @@ function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
1715
1797
  setLoading(false);
1716
1798
  }
1717
1799
  };
1718
- return /* @__PURE__ */ jsxs21(Fragment8, { children: [
1719
- /* @__PURE__ */ jsx22("style", { children: GIFT_CODE_REDEEMER_CSS }),
1720
- /* @__PURE__ */ jsx22(
1800
+ return /* @__PURE__ */ jsxs22(Fragment8, { children: [
1801
+ /* @__PURE__ */ jsx23("style", { children: GIFT_CODE_REDEEMER_CSS }),
1802
+ /* @__PURE__ */ jsx23(
1721
1803
  InlineActionField,
1722
1804
  {
1723
1805
  id,
@@ -1773,12 +1855,12 @@ async function loadJoinResume(applicationId, fetcher = fetch) {
1773
1855
  }
1774
1856
 
1775
1857
  // src/ui/join-gift-claim.tsx
1776
- import { jsx as jsx23, jsxs as jsxs22 } from "preact/jsx-runtime";
1858
+ import { jsx as jsx24, jsxs as jsxs23 } from "preact/jsx-runtime";
1777
1859
  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(
1860
+ return /* @__PURE__ */ jsxs23("section", { className: "join-gift-claim card", children: [
1861
+ /* @__PURE__ */ jsx24("div", { className: "card-label", children: props.copy.claimTitle }),
1862
+ /* @__PURE__ */ jsx24("p", { children: props.copy.claimBody }),
1863
+ /* @__PURE__ */ jsx24(
1782
1864
  GiftCodeRedeemer,
1783
1865
  {
1784
1866
  api: props.api,
@@ -1802,21 +1884,21 @@ function JoinGiftClaim(props) {
1802
1884
  }
1803
1885
 
1804
1886
  // 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";
1887
+ import { useState as useState18 } from "preact/hooks";
1888
+ import { jsx as jsx25, jsxs as jsxs24 } from "preact/jsx-runtime";
1807
1889
  function JoinNamedSeat(props) {
1808
1890
  const seatId = props.seatId ?? "";
1809
1891
  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 })
1892
+ const [accepted, setAccepted] = useState18(false), [busy, setBusy] = useState18(false), [error, setError] = useState18("");
1893
+ return /* @__PURE__ */ jsxs24("section", { className: "join-named-seat card", children: [
1894
+ /* @__PURE__ */ jsx25("h2", { children: copy.title }),
1895
+ /* @__PURE__ */ jsx25("p", { children: copy.body }),
1896
+ /* @__PURE__ */ jsxs24("label", { className: "journey-consent", children: [
1897
+ /* @__PURE__ */ jsx25("input", { type: "checkbox", checked: accepted, disabled: busy, onChange: (event) => setAccepted(event.currentTarget.checked) }),
1898
+ /* @__PURE__ */ jsx25("span", { children: copy.consent })
1817
1899
  ] }),
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 () => {
1900
+ error ? /* @__PURE__ */ jsx25("p", { role: "alert", children: error }) : null,
1901
+ /* @__PURE__ */ jsx25("button", { type: "button", className: "btn btn-primary", disabled: busy || !accepted || !seatId.trim(), onClick: async () => {
1820
1902
  setBusy(true);
1821
1903
  setError("");
1822
1904
  try {
@@ -1836,12 +1918,12 @@ function JoinNamedSeat(props) {
1836
1918
  }
1837
1919
 
1838
1920
  // 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";
1921
+ import { useEffect as useEffect8, useState as useState19 } from "preact/hooks";
1922
+ import { jsx as jsx26, jsxs as jsxs25 } from "preact/jsx-runtime";
1841
1923
  function useJoinInvitation(seatId, api, fallback) {
1842
- const [invitation, setInvitation] = useState18(null);
1843
- const [error, setError] = useState18("");
1844
- const [revision, setRevision] = useState18(0);
1924
+ const [invitation, setInvitation] = useState19(null);
1925
+ const [error, setError] = useState19("");
1926
+ const [revision, setRevision] = useState19(0);
1845
1927
  useEffect8(() => {
1846
1928
  let live = true;
1847
1929
  setInvitation(null);
@@ -1864,9 +1946,9 @@ function useJoinInvitation(seatId, api, fallback) {
1864
1946
  return { invitation: invitation?.seatId === seatId ? invitation : null, error, retry: () => setRevision((value) => value + 1) };
1865
1947
  }
1866
1948
  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 }) })
1949
+ return /* @__PURE__ */ jsxs25("aside", { className: "journey-invitation", "aria-label": props.copy.title, children: [
1950
+ /* @__PURE__ */ jsx26("p", { children: /* @__PURE__ */ jsx26("strong", { children: formatChapterCopy(props.copy.from, { purchaserName: props.invitation.purchaserName }) }) }),
1951
+ /* @__PURE__ */ jsx26("p", { children: formatChapterCopy(props.copy.prepaid, { tierName: props.tierName }) })
1870
1952
  ] });
1871
1953
  }
1872
1954
 
@@ -1906,14 +1988,14 @@ function useJoinPending(state, loadResume, setState) {
1906
1988
  }
1907
1989
 
1908
1990
  // 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";
1991
+ import { useEffect as useEffect10, useState as useState20 } from "preact/hooks";
1992
+ import { Fragment as Fragment9, jsx as jsx27, jsxs as jsxs26 } from "preact/jsx-runtime";
1911
1993
  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);
1994
+ const [receipt, setReceipt] = useState20(null);
1995
+ const [error, setError] = useState20("");
1996
+ const [revision, setRevision] = useState20(0);
1997
+ const [emailState, setEmailState] = useState20("idle");
1998
+ const [previewEmail, setPreviewEmail] = useState20(false);
1917
1999
  const endpoint = `/api/payments/receipt?application=${encodeURIComponent(applicationId)}`;
1918
2000
  useEffect10(() => {
1919
2001
  let live = true, timer;
@@ -1941,9 +2023,9 @@ function PaymentReceiptCard({ applicationId }) {
1941
2023
  if (timer) clearTimeout(timer);
1942
2024
  };
1943
2025
  }, [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" })
2026
+ if (!receipt) return error ? /* @__PURE__ */ jsxs26("section", { "aria-label": "Payment receipt", children: [
2027
+ /* @__PURE__ */ jsx27("p", { role: "status", children: error }),
2028
+ /* @__PURE__ */ jsx27("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Reload receipt" })
1947
2029
  ] }) : null;
1948
2030
  const money = (cents) => new Intl.NumberFormat("en-US", { style: "currency", currency: receipt.currency }).format(cents / 100);
1949
2031
  const email = async () => {
@@ -1960,38 +2042,38 @@ function PaymentReceiptCard({ applicationId }) {
1960
2042
  setError("We could not confirm email delivery. You can print or save your receipt.");
1961
2043
  }
1962
2044
  };
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: [
2045
+ return /* @__PURE__ */ jsxs26("section", { className: "payment-receipt card", "aria-label": "Payment receipt", children: [
2046
+ /* @__PURE__ */ jsx27("h2", { children: "Payment received" }),
2047
+ /* @__PURE__ */ jsx27("p", { children: receipt.tierName }),
2048
+ /* @__PURE__ */ jsxs26("dl", { className: "journey-summary", children: [
2049
+ /* @__PURE__ */ jsx27("dt", { children: "Membership" }),
2050
+ /* @__PURE__ */ jsx27("dd", { children: money(receipt.membershipCents) }),
2051
+ receipt.namedSeat ? /* @__PURE__ */ jsxs26(Fragment9, { children: [
2052
+ /* @__PURE__ */ jsxs26("dt", { children: [
1971
2053
  "Additional member \u2014 ",
1972
2054
  receipt.namedSeat.recipientName
1973
2055
  ] }),
1974
- /* @__PURE__ */ jsxs25("dd", { children: [
2056
+ /* @__PURE__ */ jsxs26("dd", { children: [
1975
2057
  receipt.namedSeat.amountCents === 0 ? "Included \u2014 " : "",
1976
2058
  money(receipt.namedSeat.amountCents)
1977
2059
  ] })
1978
2060
  ] }) : null,
1979
- /* @__PURE__ */ jsx26("dt", { children: "Total paid" }),
1980
- /* @__PURE__ */ jsx26("dd", { children: money(receipt.totalCents) })
2061
+ /* @__PURE__ */ jsx27("dt", { children: "Total paid" }),
2062
+ /* @__PURE__ */ jsx27("dd", { children: money(receipt.totalCents) })
1981
2063
  ] }),
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" })
2064
+ /* @__PURE__ */ jsxs26("div", { className: "journey-actions", children: [
2065
+ /* @__PURE__ */ jsx27("a", { className: "apply-link journey-secondary", href: `${endpoint}&format=html`, target: "_blank", rel: "noopener noreferrer", children: "Print / save receipt" }),
2066
+ /* @__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
2067
  ] }),
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
2068
+ 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,
2069
+ error ? /* @__PURE__ */ jsx27("p", { role: "alert", children: error }) : null
1988
2070
  ] });
1989
2071
  }
1990
2072
 
1991
2073
  // src/ui/join.tsx
1992
- import { Fragment as Fragment10, jsx as jsx27, jsxs as jsxs26 } from "preact/jsx-runtime";
2074
+ import { Fragment as Fragment10, jsx as jsx28, jsxs as jsxs27 } from "preact/jsx-runtime";
1993
2075
  function JoinIsland(props) {
1994
- return /* @__PURE__ */ jsx27(JourneyFrame, { children: /* @__PURE__ */ jsx27(JoinFlow, { ...props }) });
2076
+ return /* @__PURE__ */ jsx28(JourneyFrame, { children: /* @__PURE__ */ jsx28(JoinFlow, { ...props }) });
1995
2077
  }
1996
2078
  function JoinFlow(props) {
1997
2079
  const inheritedCopy = useChapterCopy();
@@ -2012,14 +2094,15 @@ function JoinFlow(props) {
2012
2094
  const invitation = invitationState.invitation;
2013
2095
  const selectedTierId = invitation?.skuId ?? tierSelection.selectedTierId;
2014
2096
  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);
2097
+ const [state, setState] = useState21(requestedSeat ? { step: "form" } : props.initialState ?? { step: "form" });
2098
+ const [error, setError] = useState21(null);
2099
+ const [submitting, setSubmitting] = useState21(false);
2100
+ const [editingNamedSeat, setEditingNamedSeat] = useState21(false);
2101
+ const [giftOfferId, setGiftOfferId] = useState21(props.initialGiftOfferId ?? null);
2020
2102
  const simulatedPayment = joinSimulationPayment(props.simulation, selectedTier?.priceCents ?? 0);
2021
2103
  const simulatedBooking = props.simulation ? props.simulation.booking ?? { slots: [], timezone: "UTC" } : void 0;
2022
- const submissionId = useRef7(null);
2104
+ const submissionId = useRef8(null);
2105
+ const slotsPreload = useJoinSlotsPreload(!props.simulation && ["payment", "paymentPending"].includes(state.step));
2023
2106
  useEffect11(() => {
2024
2107
  if (props.simulation) return;
2025
2108
  const resolver = requestedSeat ? () => invitation?.applicationId ? loadJoinResume(invitation.applicationId) : Promise.resolve(null) : props.loadResume ?? (() => {
@@ -2093,13 +2176,13 @@ function JoinFlow(props) {
2093
2176
  setSubmitting(false);
2094
2177
  }
2095
2178
  };
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
2179
+ if (requestedSeat && !invitation) return /* @__PURE__ */ jsxs27("section", { className: "card", "aria-live": "polite", children: [
2180
+ /* @__PURE__ */ jsx28("h2", { children: seatCopy.title }),
2181
+ /* @__PURE__ */ jsx28("p", { role: invitationState.error ? "alert" : "status", children: invitationState.error || seatCopy.loading }),
2182
+ invitationState.error ? /* @__PURE__ */ jsx28("button", { type: "button", onClick: invitationState.retry, children: seatCopy.retry }) : null
2100
2183
  ] });
2101
- const header = /* @__PURE__ */ jsxs26(Fragment10, { children: [
2102
- invitation ? /* @__PURE__ */ jsx27(
2184
+ const header = /* @__PURE__ */ jsxs27(Fragment10, { children: [
2185
+ invitation ? /* @__PURE__ */ jsx28(
2103
2186
  JoinInvitationNotice,
2104
2187
  {
2105
2188
  invitation,
@@ -2112,66 +2195,70 @@ function JoinFlow(props) {
2112
2195
  editingNamedSeat: state.step === "payment" && editingNamedSeat,
2113
2196
  ...invitation ? { invitation } : {},
2114
2197
  ..."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
2198
+ })
2117
2199
  ] });
2200
+ const receipt = !props.simulation && !requestedSeat && ["paymentPending", "booking", "accepted", "done"].includes(state.step) && "applicationId" in state ? /* @__PURE__ */ jsx28(PaymentReceiptCard, { applicationId: state.applicationId }) : null;
2118
2201
  if (state.step === "closed") {
2119
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2202
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2120
2203
  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 })
2204
+ /* @__PURE__ */ jsxs27("section", { className: "card", "aria-label": "Application closed", children: [
2205
+ /* @__PURE__ */ jsx28("h2", { children: "This application is closed" }),
2206
+ /* @__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." }),
2207
+ /* @__PURE__ */ jsx28("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
2125
2208
  ] })
2126
2209
  ] });
2127
2210
  }
2128
2211
  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 })
2212
+ const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs27("div", { className: "join-done card", children: [
2213
+ /* @__PURE__ */ jsx28("div", { className: "card-label", children: copy.done.label }),
2214
+ /* @__PURE__ */ jsx28("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
2215
+ /* @__PURE__ */ jsx28("p", { className: "meeting-note", children: copy.done.calendarInvite }),
2216
+ /* @__PURE__ */ jsx28("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
2134
2217
  ] });
2135
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2218
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2136
2219
  header,
2137
- body
2220
+ body,
2221
+ receipt
2138
2222
  ] });
2139
2223
  }
2140
2224
  if (state.step === "accepted") {
2141
- const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx27(JoinAccepted, { copy, membersHref });
2142
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2225
+ const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx28(JoinAccepted, { copy, membersHref });
2226
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2143
2227
  header,
2144
- body
2228
+ body,
2229
+ receipt
2145
2230
  ] });
2146
2231
  }
2147
2232
  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: [
2233
+ const body = renderGift?.(state) ?? /* @__PURE__ */ jsx28(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
2234
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2150
2235
  header,
2151
2236
  body
2152
2237
  ] });
2153
2238
  }
2154
2239
  if (state.step === "booking") {
2155
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2240
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2156
2241
  header,
2157
- /* @__PURE__ */ jsx27(
2242
+ /* @__PURE__ */ jsx28(
2158
2243
  JoinBooking,
2159
2244
  {
2160
2245
  applicationId: state.applicationId,
2161
2246
  copy: copy.booking,
2162
2247
  simulation: simulatedBooking,
2248
+ preload: slotsPreload,
2163
2249
  onBooked: (booked) => {
2164
2250
  setState({ step: "done", applicationId: state.applicationId, booked });
2165
2251
  }
2166
2252
  }
2167
- )
2253
+ ),
2254
+ receipt
2168
2255
  ] });
2169
2256
  }
2170
2257
  if (state.step === "payment") {
2171
2258
  if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation && !state.giftPurchase) {
2172
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2259
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2173
2260
  header,
2174
- /* @__PURE__ */ jsx27(
2261
+ /* @__PURE__ */ jsx28(
2175
2262
  JoinNamedSeat,
2176
2263
  {
2177
2264
  api: props.namedSeatClaimApi,
@@ -2184,9 +2271,9 @@ function JoinFlow(props) {
2184
2271
  ] });
2185
2272
  }
2186
2273
  const Payment = state.giftPurchase || props.simulation ? PaymentStep : MembershipPaymentStep;
2187
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2274
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2188
2275
  header,
2189
- props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx27(
2276
+ props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx28(
2190
2277
  JoinGiftClaim,
2191
2278
  {
2192
2279
  api: props.giftClaimApi,
@@ -2197,7 +2284,7 @@ function JoinFlow(props) {
2197
2284
  onError: () => setError(copy.form.unexpectedFailure)
2198
2285
  }
2199
2286
  ) : null,
2200
- /* @__PURE__ */ jsx27(
2287
+ /* @__PURE__ */ jsx28(
2201
2288
  Payment,
2202
2289
  {
2203
2290
  applicationId: state.applicationId,
@@ -2225,9 +2312,9 @@ function JoinFlow(props) {
2225
2312
  }
2226
2313
  if (state.step === "paymentPending") {
2227
2314
  if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation) {
2228
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2315
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2229
2316
  header,
2230
- /* @__PURE__ */ jsx27(
2317
+ /* @__PURE__ */ jsx28(
2231
2318
  JoinNamedSeat,
2232
2319
  {
2233
2320
  api: props.namedSeatClaimApi,
@@ -2239,14 +2326,15 @@ function JoinFlow(props) {
2239
2326
  )
2240
2327
  ] });
2241
2328
  }
2242
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2329
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2243
2330
  header,
2244
- /* @__PURE__ */ jsx27("p", { className: "pay-status", role: "status", children: copy.payment.pending })
2331
+ /* @__PURE__ */ jsx28("p", { className: "pay-status", role: "status", children: copy.payment.pending }),
2332
+ receipt
2245
2333
  ] });
2246
2334
  }
2247
- return /* @__PURE__ */ jsxs26(Fragment10, { children: [
2335
+ return /* @__PURE__ */ jsxs27(Fragment10, { children: [
2248
2336
  header,
2249
- /* @__PURE__ */ jsx27(
2337
+ /* @__PURE__ */ jsx28(
2250
2338
  JoinApplicationForm,
2251
2339
  {
2252
2340
  props,
@@ -2436,7 +2524,7 @@ function membershipPageDocument(input, options = {}) {
2436
2524
  }
2437
2525
 
2438
2526
  // src/ui/membership-cards.tsx
2439
- import { jsx as jsx28, jsxs as jsxs27 } from "preact/jsx-runtime";
2527
+ import { jsx as jsx29, jsxs as jsxs28 } from "preact/jsx-runtime";
2440
2528
  var MEMBERSHIP_CARD_TOKEN_DEFAULTS = Object.freeze({
2441
2529
  "--ui-membership-grid-gap": "1.4rem",
2442
2530
  "--ui-membership-card-padding": "2rem 1.7rem 1.8rem",
@@ -2505,67 +2593,67 @@ function membershipApplicationHref(applicationPath, tierId) {
2505
2593
  }
2506
2594
  function TierAction(props) {
2507
2595
  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: [
2596
+ return /* @__PURE__ */ jsxs28("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
2509
2597
  props.label,
2510
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192" })
2598
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: "\u2192" })
2511
2599
  ] });
2512
2600
  }
2513
2601
  if (props.mode === "preview") {
2514
- return /* @__PURE__ */ jsxs27("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
2602
+ return /* @__PURE__ */ jsxs28("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
2515
2603
  props.label,
2516
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192" })
2604
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: "\u2192" })
2517
2605
  ] });
2518
2606
  }
2519
- return /* @__PURE__ */ jsxs27("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
2607
+ return /* @__PURE__ */ jsxs28("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
2520
2608
  props.label,
2521
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192" })
2609
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: "\u2192" })
2522
2610
  ] });
2523
2611
  }
2524
2612
  function TierCard(props) {
2525
2613
  const { tier, presentation } = props;
2526
2614
  const summary = presentation.summaryMarkdown ?? tier.blurb;
2527
2615
  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" })
2616
+ return /* @__PURE__ */ jsxs28("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
2617
+ presentation.badge ? /* @__PURE__ */ jsx29("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
2618
+ /* @__PURE__ */ jsx29("h3", { className: "chapter-membership-name", children: tier.name }),
2619
+ /* @__PURE__ */ jsxs28("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
2620
+ presentation.capacity ? /* @__PURE__ */ jsxs28("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
2621
+ /* @__PURE__ */ jsx29("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
2622
+ /* @__PURE__ */ jsx29("small", { children: presentation.capacity.label ?? "available" })
2535
2623
  ] }) : 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
2624
+ /* @__PURE__ */ jsxs28("div", { className: "chapter-membership-price-stack", children: [
2625
+ 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,
2626
+ /* @__PURE__ */ jsxs28("div", { className: "chapter-membership-price-row", children: [
2627
+ 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,
2628
+ /* @__PURE__ */ jsx29("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.founding ? tier.founding.dueTodayCents : tier.priceCents) }),
2629
+ !tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx29("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
2542
2630
  ] })
2543
2631
  ] })
2544
2632
  ] }),
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 })
2633
+ presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx29(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
2634
+ summary ? /* @__PURE__ */ jsx29(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
2635
+ presentation.benefits?.length ? /* @__PURE__ */ jsx29("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs28("li", { children: [
2636
+ /* @__PURE__ */ jsx29("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
2637
+ /* @__PURE__ */ jsx29(Markdown2, { className: "chapter-membership-benefit", source: benefit })
2550
2638
  ] }, `${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 })
2639
+ presentation.callout ? /* @__PURE__ */ jsxs28("aside", { className: "chapter-membership-callout", children: [
2640
+ presentation.callout.label ? /* @__PURE__ */ jsx29("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
2641
+ /* @__PURE__ */ jsx29(Markdown2, { source: presentation.callout.bodyMarkdown })
2554
2642
  ] }) : null,
2555
- /* @__PURE__ */ jsx28(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
2643
+ /* @__PURE__ */ jsx29(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
2556
2644
  ] });
2557
2645
  }
2558
2646
  function MembershipCards(props) {
2559
2647
  const document2 = membershipPageDocument(props.document, { tiers: props.tiers });
2560
2648
  const byId = new Map(props.tiers.map((tier) => [tier.id, tier]));
2561
2649
  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) => {
2650
+ 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: [
2651
+ /* @__PURE__ */ jsx29("style", { children: MEMBERSHIP_CARDS_CSS }),
2652
+ /* @__PURE__ */ jsx29("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
2565
2653
  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);
2654
+ return /* @__PURE__ */ jsx29(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
2567
2655
  }) }),
2568
- document2.footnoteMarkdown ? /* @__PURE__ */ jsx28(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
2656
+ document2.footnoteMarkdown ? /* @__PURE__ */ jsx29(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
2569
2657
  ] });
2570
2658
  }
2571
2659
 
@@ -2591,6 +2679,10 @@ export {
2591
2679
  GiftOfferCards,
2592
2680
  GiftPurchases,
2593
2681
  MemberGifts,
2682
+ namedSeatInvitationShareable,
2683
+ namedSeatInvitationUrl,
2684
+ namedSeatInvitationMessage,
2685
+ NamedSeatInvitationLink,
2594
2686
  NAMED_SEAT_RECIPIENT_WORDS,
2595
2687
  NamedSeatRecipientLine,
2596
2688
  NamedSeatPurchase,
@@ -2606,4 +2698,4 @@ export {
2606
2698
  membershipApplicationHref,
2607
2699
  MembershipCards
2608
2700
  };
2609
- //# sourceMappingURL=chunk-CKC6X5H2.js.map
2701
+ //# sourceMappingURL=chunk-SDGVPIXF.js.map