@realiizlabs/admin 0.10.2 → 0.11.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.
@@ -32,6 +32,18 @@ var FORM_CSS = `
32
32
  .realiiz-form__control--textarea{min-height:110px;resize:vertical}
33
33
  .realiiz-form__control--body{min-height:280px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px}
34
34
  .realiiz-form__control--invalid{border-color:var(--_danger)}
35
+ .realiiz-select{position:relative}
36
+ .realiiz-select__btn{display:flex;align-items:center;justify-content:space-between;gap:10px;text-align:left;cursor:pointer;background:#fff}
37
+ .realiiz-select__btn svg{flex-shrink:0;color:var(--_muted);transition:transform .15s}
38
+ .realiiz-select__btn--open{border-color:var(--_accent);box-shadow:var(--_ring)}
39
+ .realiiz-select__btn--open svg{transform:rotate(180deg)}
40
+ .realiiz-select__btn:disabled{opacity:.6;cursor:default}
41
+ .realiiz-select__placeholder{color:var(--_muted)}
42
+ .realiiz-select__menu{position:absolute;left:0;right:0;top:calc(100% + 6px);margin:0;padding:6px 0;list-style:none;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius);box-shadow:0 8px 24px rgba(14,23,38,.14);max-height:260px;overflow:auto;z-index:40}
43
+ .realiiz-select__item{display:flex;align-items:center;gap:8px;padding:8px 12px;font-size:14px;color:var(--_fg);cursor:pointer}
44
+ .realiiz-select__item--active{background:var(--realiiz-form-hover,rgba(0,0,0,.05))}
45
+ .realiiz-select__item--selected{font-weight:600}
46
+ .realiiz-select__check{width:1em;flex-shrink:0;color:var(--_accent);font-weight:700}
35
47
  .realiiz-form__check{display:flex;align-items:center;gap:8px;font-weight:500}
36
48
  .realiiz-form__check input{width:18px;height:18px;margin:0}
37
49
  .realiiz-form__helper{display:flex;justify-content:space-between;gap:12px;font-size:12px;color:var(--_muted);margin-top:4px;min-height:1em}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/forms-ui/styles.ts","../../src/auth-ui/MagicLinkForm.tsx","../../src/auth-ui/SignOutButton.tsx"],"names":["useMemo","createBrowserClient","useState","jsxs","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Theming hooks, same convention as BookingWidget: a root class, BEM elements,\n * and --realiiz-form-* custom properties with fallbacks so the form is usable\n * with zero host CSS and fully themeable with a dozen variables.\n */\n\nexport const FORM_CSS = `\n.realiiz-form{\n --_fg:var(--realiiz-form-fg,#111);\n --_muted:var(--realiiz-form-muted,#666);\n --_border:var(--realiiz-form-border,#cfcfcf);\n --_accent:var(--realiiz-form-accent,#111);\n --_accent-fg:var(--realiiz-form-accent-fg,#fff);\n --_danger:var(--realiiz-form-danger,#b3261e);\n --_radius:var(--realiiz-form-radius,6px);\n --_font:var(--realiiz-form-font,system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif);\n --_ring:var(--realiiz-form-focus-ring,0 0 0 3px rgba(0,0,0,.15));\n box-sizing:border-box;max-width:100%;color:var(--_fg);font-family:var(--_font);font-size:15px;line-height:1.4;\n}\n.realiiz-form *,.realiiz-form *::before,.realiiz-form *::after{box-sizing:inherit}\n.realiiz-form fieldset{border:0;margin:0 0 20px;padding:0;min-width:0}\n.realiiz-form legend{font-weight:600;font-size:13px;letter-spacing:.02em;text-transform:uppercase;color:var(--_muted);margin-bottom:12px;padding:0}\n.realiiz-form__field{display:block;margin:0 0 16px}\n.realiiz-form__label{display:block;font-weight:500;margin-bottom:6px}\n.realiiz-form__required{color:var(--_danger);margin-left:3px}\n.realiiz-form__control{display:block;width:100%;max-width:100%;font:inherit;color:inherit;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius);padding:9px 11px;min-height:40px}\n.realiiz-form__control:focus{outline:none;border-color:var(--_accent);box-shadow:var(--_ring)}\n.realiiz-form__control--textarea{min-height:110px;resize:vertical}\n.realiiz-form__control--body{min-height:280px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px}\n.realiiz-form__control--invalid{border-color:var(--_danger)}\n.realiiz-form__check{display:flex;align-items:center;gap:8px;font-weight:500}\n.realiiz-form__check input{width:18px;height:18px;margin:0}\n.realiiz-form__helper{display:flex;justify-content:space-between;gap:12px;font-size:12px;color:var(--_muted);margin-top:4px;min-height:1em}\n.realiiz-form__count{margin-left:auto;font-variant-numeric:tabular-nums}\n.realiiz-form__error{color:var(--_danger);font-size:13px;margin-top:4px}\n.realiiz-image{border:1px dashed var(--_border);border-radius:var(--_radius);padding:16px 18px;background:#fff;outline:none;transition:border-color .15s}\n.realiiz-image--over{border-color:var(--_accent);border-style:solid}\n.realiiz-image--invalid{border-color:var(--_danger)}\n.realiiz-image--busy{opacity:.7}\n.realiiz-image__empty{display:flex;align-items:center;gap:14px;flex-wrap:wrap;color:var(--_muted)}\n.realiiz-image__icon{flex-shrink:0;color:var(--_muted)}\n.realiiz-image__or{font-size:13px}\n.realiiz-image__has{display:flex;align-items:flex-start;gap:16px}\n.realiiz-image__thumb{display:block;max-height:160px;max-width:min(320px,55%);width:auto;object-fit:cover;border-radius:8px;border:1px solid var(--_border);background:#f6f8fa}\n.realiiz-image__meta{display:flex;flex-direction:column;gap:10px;min-width:0}\n.realiiz-image__detail{font-size:13px;color:var(--_muted);word-break:break-all}\n.realiiz-image__actions{display:flex;align-items:center;gap:14px}\n.realiiz-image__remove{font:inherit;font-size:13px;background:none;border:0;padding:0;color:var(--_muted);text-decoration:underline;text-underline-offset:3px;cursor:pointer}\n.realiiz-image__remove:hover{color:var(--_danger)}\n.realiiz-image__hint{font-size:12px;color:var(--_muted);margin-top:10px}\n.realiiz-image .realiiz-form__error{margin-top:8px}\n@media (max-width:720px){.realiiz-image__has{flex-direction:column}.realiiz-image__thumb{max-width:100%}}\n.realiiz-form__alert{border:1px solid var(--_danger);border-radius:var(--_radius);padding:12px 14px;margin:0 0 20px;color:var(--_danger)}\n.realiiz-form__alert ul{margin:6px 0 0;padding-left:18px}\n.realiiz-form__actions{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;margin-top:8px}\n.realiiz-form__help{text-decoration:underline dotted;text-decoration-color:color-mix(in srgb,currentColor 45%,transparent);text-underline-offset:4px;cursor:help}\n.realiiz-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n.realiiz-form__footer{max-width:920px}\n.realiiz-form__bar{display:flex;align-items:center;gap:10px;margin-top:16px;padding:12px 0;border-top:1px solid var(--_border);background:#fff}\n.realiiz-form__status{margin-right:auto;font-size:.85rem;color:var(--_muted)}\n.realiiz-form__bar[data-dirty] .realiiz-form__status{color:var(--_fg)}\n.realiiz-form__button{font:inherit;font-weight:600;border-radius:var(--_radius);padding:10px 16px;border:1px solid var(--_border);background:#fff;color:var(--_fg);cursor:pointer;min-height:40px}\n.realiiz-form__button--primary{background:var(--_accent);color:var(--_accent-fg);border-color:var(--_accent)}\n.realiiz-form__button:disabled{opacity:.6;cursor:default}\n.realiiz-md{--_md-head:#fafbfd;--_md-hover:#f4f8fd;--_md-hover-line:#bcd0ea;--_md-on:#eef4fb;--_md-tip:#1f2933;position:relative}\n.realiiz-md__mode{display:inline-flex;align-self:flex-start;width:max-content;gap:2px;padding:3px;background:color-mix(in srgb,var(--_border) 40%,transparent);border-radius:8px;margin-bottom:8px}\n.realiiz-md__mode button{font:inherit;font-size:.8rem;padding:5px 13px;border:0;border-radius:6px;background:transparent;color:var(--_muted);cursor:pointer}\n.realiiz-md__mode button[aria-selected=\"true\"]{background:#fff;color:var(--_fg);box-shadow:0 1px 2px rgba(0,0,0,.12)}\n.realiiz-md__panel{position:relative;z-index:0;display:flex;flex-direction:column;border:1px solid var(--_border);border-radius:10px;background:#fff;overflow:hidden}\n.realiiz-md__panel:focus-within{border-color:var(--_md-hover-line)}\n.realiiz-md__head{position:relative;z-index:5;display:flex;align-items:center;gap:2px;flex-wrap:wrap;padding:5px 7px;background:var(--_md-head);border-bottom:1px solid var(--_border);flex-shrink:0}\n.realiiz-md__tools{display:flex;align-items:center;gap:3px;flex-wrap:wrap}\n.realiiz-md__spacer{flex:1}\n.realiiz-md__head button{position:relative;min-width:31px;height:28px;padding:0 9px;display:inline-flex;align-items:center;justify-content:center;background:#fff;border:1px solid var(--_border);border-radius:6px;font-family:inherit;font-size:.82rem;color:var(--_fg);cursor:pointer;line-height:1}\n.realiiz-md__head button:hover:not(:disabled){border-color:var(--_md-hover-line);background:var(--_md-hover)}\n.realiiz-md__head button:active{background:var(--_md-on)}\n.realiiz-md__head button.on{background:var(--_md-on);border-color:var(--_accent);color:var(--_accent);font-weight:600}\n.realiiz-md__ico{width:15px;height:15px;display:block}\n.realiiz-md__dot{font-size:1.05rem;line-height:1}\n.realiiz-md__sep{width:1px;height:17px;background:var(--_border);margin:0 5px}\n.realiiz-md__insert{display:inline-flex;align-items:center;gap:3px;border-left:1px solid var(--_border);padding-left:8px;margin-left:6px}\n.realiiz-md__insert button{background:#f6f8fa;color:var(--_muted);padding:0;width:31px}\n.realiiz-md__insert button:hover{color:var(--_accent)}\n.realiiz-md__lab{font-size:.74rem;color:var(--_muted);margin-right:3px}\n.realiiz-md__head button[data-tip]::after{content:attr(data-tip);position:absolute;top:calc(100% + 6px);left:0;background:var(--_md-tip);color:#fff;font-size:.72rem;padding:4px 8px;border-radius:5px;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .12s;z-index:20}\n.realiiz-md__head button[data-tip]:hover::after,.realiiz-md__head button[data-tip]:focus-visible::after{opacity:1}\n.realiiz-md__expand[data-tip]::after{left:auto;right:0}\n.realiiz-md__tgwrap{position:relative;display:inline-flex}\n.realiiz-md__tgrid{position:absolute;top:calc(100% + 6px);left:0;background:#fff;border:1px solid var(--_border);border-radius:9px;padding:9px;box-shadow:0 10px 28px rgba(0,0,0,.14);z-index:7;display:block}\n.realiiz-md__tgcells{display:grid;grid-template-columns:repeat(6,17px);gap:3px}\n.realiiz-md__tgcells i{width:17px;height:15px;border:1px solid var(--_border);border-radius:2px;background:#fff;cursor:pointer;display:block}\n.realiiz-md__tgcells i.hot{background:#dbe9fb;border-color:var(--_accent)}\n.realiiz-md__tglab{display:block;margin-top:8px;font-size:.74rem;color:var(--_muted);text-align:center;white-space:nowrap}\n.realiiz-md .realiiz-md__ta{flex:1 1 auto;border:0;border-radius:0;resize:vertical;background:#fff;max-width:none;padding:16px 18px;line-height:1.65}\n.realiiz-md .realiiz-md__ta:focus{outline:none;box-shadow:none}\n.realiiz-md__preview{padding:20px 24px;background:#fff}\n.realiiz-md__note{padding:4px 2px}\n.realiiz-md--fs{position:fixed;inset:0;z-index:60;background:#fff;padding:14px 22px 22px;overflow:auto;display:flex;flex-direction:column}\n.realiiz-md--fs .realiiz-md__panel{flex:1;min-height:0}\n.realiiz-md--fs .realiiz-md__ta,.realiiz-md--fs .realiiz-md__preview{flex:1;min-height:0;overflow:auto;resize:none}\n.realiiz-prose{max-width:68ch;line-height:1.65}\n.realiiz-chips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;min-height:40px;padding:5px 8px;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius)}\n.realiiz-chips:focus-within{border-color:var(--_accent);box-shadow:var(--_ring)}\n.realiiz-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 9px;border:1px solid var(--_border);border-radius:999px;font-size:.8rem}\n.realiiz-chip button{font:inherit;line-height:1;width:18px;height:18px;border-radius:50%;border:0;background:transparent;color:var(--_muted);cursor:pointer}\n.realiiz-chips__input{flex:1;min-width:120px;border:0;background:transparent;font:inherit;color:inherit;outline:none;padding:4px}\n.realiiz-chips__count{margin-left:auto;color:var(--_muted);font-size:.75rem}\n.realiiz-gauge{display:inline-flex;align-items:center;gap:10px;font-size:.75rem;color:var(--_muted)}\n.realiiz-gauge__bar{position:relative;width:140px;height:6px;border-radius:3px;background:var(--_border);overflow:hidden}\n.realiiz-gauge__zone{position:absolute;top:0;bottom:0;background:rgba(21,128,61,.28)}\n.realiiz-gauge__fill{position:absolute;top:0;bottom:0;left:0;background:var(--_muted);border-radius:3px;transition:width .12s}\n.realiiz-gauge__text b{font-weight:600;color:inherit}\n.realiiz-gauge--ok{color:#15803d}.realiiz-gauge--ok .realiiz-gauge__fill{background:#15803d}\n.realiiz-gauge--over{color:var(--_danger)}.realiiz-gauge--over .realiiz-gauge__fill{background:var(--_danger)}\n`;\n","/**\n * MagicLinkForm — one field, one button, and the right words for each outcome.\n *\n * The audience is a non-technical client. Two outcomes matter:\n * sent → tell them where the link went and that it expires in an hour\n * uninvited → signups are off, so Supabase refuses unknown emails with a\n * \"Signups not allowed\" error. That string is a support ticket;\n * \"this email isn't set up for this site\" is not.\n *\n * `shouldCreateUser: false` restates the dashboard setting in code — the flag\n * a reviewer greps for.\n */\n\nimport { createBrowserClient } from \"@supabase/ssr\";\nimport { useMemo, useState, type FormEvent } from \"react\";\nimport { FORM_CSS } from \"../forms-ui/styles\";\n\nexport interface MagicLinkFormProps {\n url: string;\n anonKey: string;\n /** The site's callback, e.g. https://5degrees.org/admin/auth/callback?next=/admin */\n redirectTo: string;\n /** Shown in the heading: \"Sign in to {siteName}\". */\n siteName: string;\n className?: string;\n}\n\ntype State = { kind: \"idle\" } | { kind: \"sending\" } | { kind: \"sent\"; email: string } | { kind: \"error\"; message: string; uninvited: boolean };\n\nexport const UNINVITED_MESSAGE =\n \"This email address isn't set up for this site yet. Ask the site owner to send you an invite.\";\n\nexport function isUninvitedError(message: string): boolean {\n return /signups? not allowed|not allowed|user not found|invalid login/i.test(message);\n}\n\nexport function MagicLinkForm({ url, anonKey, redirectTo, siteName, className }: MagicLinkFormProps) {\n const supabase = useMemo(() => createBrowserClient(url, anonKey), [url, anonKey]);\n const [email, setEmail] = useState(\"\");\n const [state, setState] = useState<State>({ kind: \"idle\" });\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n if (state.kind === \"sending\") return;\n const address = email.trim().toLowerCase();\n setState({ kind: \"sending\" });\n const { error } = await supabase.auth.signInWithOtp({\n email: address,\n options: { emailRedirectTo: redirectTo, shouldCreateUser: false },\n });\n if (error) {\n const uninvited = isUninvitedError(error.message);\n setState({ kind: \"error\", message: uninvited ? UNINVITED_MESSAGE : error.message, uninvited });\n return;\n }\n setState({ kind: \"sent\", email: address });\n };\n\n const root = [\"realiiz-form\", \"realiiz-signin\", className].filter(Boolean).join(\" \");\n\n if (state.kind === \"sent\") {\n return (\n <div className={root} data-realiiz-signin=\"sent\">\n <style>{FORM_CSS}</style>\n <h2 className=\"realiiz-signin__heading\">Check your email</h2>\n <p>\n We sent a sign-in link to <strong>{state.email}</strong>. It expires in an hour.\n </p>\n <button type=\"button\" className=\"realiiz-form__button\" onClick={() => setState({ kind: \"idle\" })}>\n Use a different address\n </button>\n </div>\n );\n }\n\n const sending = state.kind === \"sending\";\n const fieldError = state.kind === \"error\" && !state.uninvited ? state.message : null;\n\n return (\n <form className={root} onSubmit={submit} noValidate data-realiiz-signin=\"form\">\n <style>{FORM_CSS}</style>\n <h2 className=\"realiiz-signin__heading\">Sign in to {siteName}</h2>\n\n {state.kind === \"error\" && state.uninvited && (\n <div className=\"realiiz-form__alert\" role=\"alert\">{state.message}</div>\n )}\n\n <div className=\"realiiz-form__field\">\n <label className=\"realiiz-form__label\" htmlFor=\"realiiz-signin-email\">Email address</label>\n <input\n id=\"realiiz-signin-email\"\n className={[\"realiiz-form__control\", fieldError && \"realiiz-form__control--invalid\"].filter(Boolean).join(\" \")}\n type=\"email\"\n name=\"email\"\n autoComplete=\"email\"\n required\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n aria-invalid={fieldError ? true : undefined}\n aria-describedby={fieldError ? \"realiiz-signin-email-error\" : undefined}\n />\n {fieldError && (\n <div className=\"realiiz-form__error\" id=\"realiiz-signin-email-error\">{fieldError}</div>\n )}\n </div>\n\n <div className=\"realiiz-form__actions\">\n <button type=\"submit\" className=\"realiiz-form__button realiiz-form__button--primary\" disabled={sending || email.trim() === \"\"}>\n {sending ? \"Sending…\" : \"Send me a sign-in link\"}\n </button>\n </div>\n </form>\n );\n}\n","/**\n * SignOutButton — a plain POST form. No JavaScript needed, so it works before\n * hydration and inside a server component. The site's route (ADMIN-04) calls\n * signOut() from @realiizlabs/admin/auth and redirects.\n */\n\nexport interface SignOutButtonProps {\n /** Default \"/admin/auth/signout\". */\n actionPath?: string;\n className?: string;\n label?: string;\n}\n\nexport function SignOutButton({ actionPath = \"/admin/auth/signout\", className, label = \"Sign out\" }: SignOutButtonProps) {\n return (\n <form method=\"post\" action={actionPath} className={[\"realiiz-signout\", className].filter(Boolean).join(\" \")}>\n <button type=\"submit\" className=\"realiiz-form__button\">{label}</button>\n </form>\n );\n}\n"]}
1
+ {"version":3,"sources":["../../src/forms-ui/styles.ts","../../src/auth-ui/MagicLinkForm.tsx","../../src/auth-ui/SignOutButton.tsx"],"names":["useMemo","createBrowserClient","useState","jsxs","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Theming hooks, same convention as BookingWidget: a root class, BEM elements,\n * and --realiiz-form-* custom properties with fallbacks so the form is usable\n * with zero host CSS and fully themeable with a dozen variables.\n */\n\nexport const FORM_CSS = `\n.realiiz-form{\n --_fg:var(--realiiz-form-fg,#111);\n --_muted:var(--realiiz-form-muted,#666);\n --_border:var(--realiiz-form-border,#cfcfcf);\n --_accent:var(--realiiz-form-accent,#111);\n --_accent-fg:var(--realiiz-form-accent-fg,#fff);\n --_danger:var(--realiiz-form-danger,#b3261e);\n --_radius:var(--realiiz-form-radius,6px);\n --_font:var(--realiiz-form-font,system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif);\n --_ring:var(--realiiz-form-focus-ring,0 0 0 3px rgba(0,0,0,.15));\n box-sizing:border-box;max-width:100%;color:var(--_fg);font-family:var(--_font);font-size:15px;line-height:1.4;\n}\n.realiiz-form *,.realiiz-form *::before,.realiiz-form *::after{box-sizing:inherit}\n.realiiz-form fieldset{border:0;margin:0 0 20px;padding:0;min-width:0}\n.realiiz-form legend{font-weight:600;font-size:13px;letter-spacing:.02em;text-transform:uppercase;color:var(--_muted);margin-bottom:12px;padding:0}\n.realiiz-form__field{display:block;margin:0 0 16px}\n.realiiz-form__label{display:block;font-weight:500;margin-bottom:6px}\n.realiiz-form__required{color:var(--_danger);margin-left:3px}\n.realiiz-form__control{display:block;width:100%;max-width:100%;font:inherit;color:inherit;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius);padding:9px 11px;min-height:40px}\n.realiiz-form__control:focus{outline:none;border-color:var(--_accent);box-shadow:var(--_ring)}\n.realiiz-form__control--textarea{min-height:110px;resize:vertical}\n.realiiz-form__control--body{min-height:280px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px}\n.realiiz-form__control--invalid{border-color:var(--_danger)}\n.realiiz-select{position:relative}\n.realiiz-select__btn{display:flex;align-items:center;justify-content:space-between;gap:10px;text-align:left;cursor:pointer;background:#fff}\n.realiiz-select__btn svg{flex-shrink:0;color:var(--_muted);transition:transform .15s}\n.realiiz-select__btn--open{border-color:var(--_accent);box-shadow:var(--_ring)}\n.realiiz-select__btn--open svg{transform:rotate(180deg)}\n.realiiz-select__btn:disabled{opacity:.6;cursor:default}\n.realiiz-select__placeholder{color:var(--_muted)}\n.realiiz-select__menu{position:absolute;left:0;right:0;top:calc(100% + 6px);margin:0;padding:6px 0;list-style:none;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius);box-shadow:0 8px 24px rgba(14,23,38,.14);max-height:260px;overflow:auto;z-index:40}\n.realiiz-select__item{display:flex;align-items:center;gap:8px;padding:8px 12px;font-size:14px;color:var(--_fg);cursor:pointer}\n.realiiz-select__item--active{background:var(--realiiz-form-hover,rgba(0,0,0,.05))}\n.realiiz-select__item--selected{font-weight:600}\n.realiiz-select__check{width:1em;flex-shrink:0;color:var(--_accent);font-weight:700}\n.realiiz-form__check{display:flex;align-items:center;gap:8px;font-weight:500}\n.realiiz-form__check input{width:18px;height:18px;margin:0}\n.realiiz-form__helper{display:flex;justify-content:space-between;gap:12px;font-size:12px;color:var(--_muted);margin-top:4px;min-height:1em}\n.realiiz-form__count{margin-left:auto;font-variant-numeric:tabular-nums}\n.realiiz-form__error{color:var(--_danger);font-size:13px;margin-top:4px}\n.realiiz-image{border:1px dashed var(--_border);border-radius:var(--_radius);padding:16px 18px;background:#fff;outline:none;transition:border-color .15s}\n.realiiz-image--over{border-color:var(--_accent);border-style:solid}\n.realiiz-image--invalid{border-color:var(--_danger)}\n.realiiz-image--busy{opacity:.7}\n.realiiz-image__empty{display:flex;align-items:center;gap:14px;flex-wrap:wrap;color:var(--_muted)}\n.realiiz-image__icon{flex-shrink:0;color:var(--_muted)}\n.realiiz-image__or{font-size:13px}\n.realiiz-image__has{display:flex;align-items:flex-start;gap:16px}\n.realiiz-image__thumb{display:block;max-height:160px;max-width:min(320px,55%);width:auto;object-fit:cover;border-radius:8px;border:1px solid var(--_border);background:#f6f8fa}\n.realiiz-image__meta{display:flex;flex-direction:column;gap:10px;min-width:0}\n.realiiz-image__detail{font-size:13px;color:var(--_muted);word-break:break-all}\n.realiiz-image__actions{display:flex;align-items:center;gap:14px}\n.realiiz-image__remove{font:inherit;font-size:13px;background:none;border:0;padding:0;color:var(--_muted);text-decoration:underline;text-underline-offset:3px;cursor:pointer}\n.realiiz-image__remove:hover{color:var(--_danger)}\n.realiiz-image__hint{font-size:12px;color:var(--_muted);margin-top:10px}\n.realiiz-image .realiiz-form__error{margin-top:8px}\n@media (max-width:720px){.realiiz-image__has{flex-direction:column}.realiiz-image__thumb{max-width:100%}}\n.realiiz-form__alert{border:1px solid var(--_danger);border-radius:var(--_radius);padding:12px 14px;margin:0 0 20px;color:var(--_danger)}\n.realiiz-form__alert ul{margin:6px 0 0;padding-left:18px}\n.realiiz-form__actions{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;margin-top:8px}\n.realiiz-form__help{text-decoration:underline dotted;text-decoration-color:color-mix(in srgb,currentColor 45%,transparent);text-underline-offset:4px;cursor:help}\n.realiiz-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n.realiiz-form__footer{max-width:920px}\n.realiiz-form__bar{display:flex;align-items:center;gap:10px;margin-top:16px;padding:12px 0;border-top:1px solid var(--_border);background:#fff}\n.realiiz-form__status{margin-right:auto;font-size:.85rem;color:var(--_muted)}\n.realiiz-form__bar[data-dirty] .realiiz-form__status{color:var(--_fg)}\n.realiiz-form__button{font:inherit;font-weight:600;border-radius:var(--_radius);padding:10px 16px;border:1px solid var(--_border);background:#fff;color:var(--_fg);cursor:pointer;min-height:40px}\n.realiiz-form__button--primary{background:var(--_accent);color:var(--_accent-fg);border-color:var(--_accent)}\n.realiiz-form__button:disabled{opacity:.6;cursor:default}\n.realiiz-md{--_md-head:#fafbfd;--_md-hover:#f4f8fd;--_md-hover-line:#bcd0ea;--_md-on:#eef4fb;--_md-tip:#1f2933;position:relative}\n.realiiz-md__mode{display:inline-flex;align-self:flex-start;width:max-content;gap:2px;padding:3px;background:color-mix(in srgb,var(--_border) 40%,transparent);border-radius:8px;margin-bottom:8px}\n.realiiz-md__mode button{font:inherit;font-size:.8rem;padding:5px 13px;border:0;border-radius:6px;background:transparent;color:var(--_muted);cursor:pointer}\n.realiiz-md__mode button[aria-selected=\"true\"]{background:#fff;color:var(--_fg);box-shadow:0 1px 2px rgba(0,0,0,.12)}\n.realiiz-md__panel{position:relative;z-index:0;display:flex;flex-direction:column;border:1px solid var(--_border);border-radius:10px;background:#fff;overflow:hidden}\n.realiiz-md__panel:focus-within{border-color:var(--_md-hover-line)}\n.realiiz-md__head{position:relative;z-index:5;display:flex;align-items:center;gap:2px;flex-wrap:wrap;padding:5px 7px;background:var(--_md-head);border-bottom:1px solid var(--_border);flex-shrink:0}\n.realiiz-md__tools{display:flex;align-items:center;gap:3px;flex-wrap:wrap}\n.realiiz-md__spacer{flex:1}\n.realiiz-md__head button{position:relative;min-width:31px;height:28px;padding:0 9px;display:inline-flex;align-items:center;justify-content:center;background:#fff;border:1px solid var(--_border);border-radius:6px;font-family:inherit;font-size:.82rem;color:var(--_fg);cursor:pointer;line-height:1}\n.realiiz-md__head button:hover:not(:disabled){border-color:var(--_md-hover-line);background:var(--_md-hover)}\n.realiiz-md__head button:active{background:var(--_md-on)}\n.realiiz-md__head button.on{background:var(--_md-on);border-color:var(--_accent);color:var(--_accent);font-weight:600}\n.realiiz-md__ico{width:15px;height:15px;display:block}\n.realiiz-md__dot{font-size:1.05rem;line-height:1}\n.realiiz-md__sep{width:1px;height:17px;background:var(--_border);margin:0 5px}\n.realiiz-md__insert{display:inline-flex;align-items:center;gap:3px;border-left:1px solid var(--_border);padding-left:8px;margin-left:6px}\n.realiiz-md__insert button{background:#f6f8fa;color:var(--_muted);padding:0;width:31px}\n.realiiz-md__insert button:hover{color:var(--_accent)}\n.realiiz-md__lab{font-size:.74rem;color:var(--_muted);margin-right:3px}\n.realiiz-md__head button[data-tip]::after{content:attr(data-tip);position:absolute;top:calc(100% + 6px);left:0;background:var(--_md-tip);color:#fff;font-size:.72rem;padding:4px 8px;border-radius:5px;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .12s;z-index:20}\n.realiiz-md__head button[data-tip]:hover::after,.realiiz-md__head button[data-tip]:focus-visible::after{opacity:1}\n.realiiz-md__expand[data-tip]::after{left:auto;right:0}\n.realiiz-md__tgwrap{position:relative;display:inline-flex}\n.realiiz-md__tgrid{position:absolute;top:calc(100% + 6px);left:0;background:#fff;border:1px solid var(--_border);border-radius:9px;padding:9px;box-shadow:0 10px 28px rgba(0,0,0,.14);z-index:7;display:block}\n.realiiz-md__tgcells{display:grid;grid-template-columns:repeat(6,17px);gap:3px}\n.realiiz-md__tgcells i{width:17px;height:15px;border:1px solid var(--_border);border-radius:2px;background:#fff;cursor:pointer;display:block}\n.realiiz-md__tgcells i.hot{background:#dbe9fb;border-color:var(--_accent)}\n.realiiz-md__tglab{display:block;margin-top:8px;font-size:.74rem;color:var(--_muted);text-align:center;white-space:nowrap}\n.realiiz-md .realiiz-md__ta{flex:1 1 auto;border:0;border-radius:0;resize:vertical;background:#fff;max-width:none;padding:16px 18px;line-height:1.65}\n.realiiz-md .realiiz-md__ta:focus{outline:none;box-shadow:none}\n.realiiz-md__preview{padding:20px 24px;background:#fff}\n.realiiz-md__note{padding:4px 2px}\n.realiiz-md--fs{position:fixed;inset:0;z-index:60;background:#fff;padding:14px 22px 22px;overflow:auto;display:flex;flex-direction:column}\n.realiiz-md--fs .realiiz-md__panel{flex:1;min-height:0}\n.realiiz-md--fs .realiiz-md__ta,.realiiz-md--fs .realiiz-md__preview{flex:1;min-height:0;overflow:auto;resize:none}\n.realiiz-prose{max-width:68ch;line-height:1.65}\n.realiiz-chips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;min-height:40px;padding:5px 8px;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius)}\n.realiiz-chips:focus-within{border-color:var(--_accent);box-shadow:var(--_ring)}\n.realiiz-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 9px;border:1px solid var(--_border);border-radius:999px;font-size:.8rem}\n.realiiz-chip button{font:inherit;line-height:1;width:18px;height:18px;border-radius:50%;border:0;background:transparent;color:var(--_muted);cursor:pointer}\n.realiiz-chips__input{flex:1;min-width:120px;border:0;background:transparent;font:inherit;color:inherit;outline:none;padding:4px}\n.realiiz-chips__count{margin-left:auto;color:var(--_muted);font-size:.75rem}\n.realiiz-gauge{display:inline-flex;align-items:center;gap:10px;font-size:.75rem;color:var(--_muted)}\n.realiiz-gauge__bar{position:relative;width:140px;height:6px;border-radius:3px;background:var(--_border);overflow:hidden}\n.realiiz-gauge__zone{position:absolute;top:0;bottom:0;background:rgba(21,128,61,.28)}\n.realiiz-gauge__fill{position:absolute;top:0;bottom:0;left:0;background:var(--_muted);border-radius:3px;transition:width .12s}\n.realiiz-gauge__text b{font-weight:600;color:inherit}\n.realiiz-gauge--ok{color:#15803d}.realiiz-gauge--ok .realiiz-gauge__fill{background:#15803d}\n.realiiz-gauge--over{color:var(--_danger)}.realiiz-gauge--over .realiiz-gauge__fill{background:var(--_danger)}\n`;\n","/**\n * MagicLinkForm — one field, one button, and the right words for each outcome.\n *\n * The audience is a non-technical client. Two outcomes matter:\n * sent → tell them where the link went and that it expires in an hour\n * uninvited → signups are off, so Supabase refuses unknown emails with a\n * \"Signups not allowed\" error. That string is a support ticket;\n * \"this email isn't set up for this site\" is not.\n *\n * `shouldCreateUser: false` restates the dashboard setting in code — the flag\n * a reviewer greps for.\n */\n\nimport { createBrowserClient } from \"@supabase/ssr\";\nimport { useMemo, useState, type FormEvent } from \"react\";\nimport { FORM_CSS } from \"../forms-ui/styles\";\n\nexport interface MagicLinkFormProps {\n url: string;\n anonKey: string;\n /** The site's callback, e.g. https://5degrees.org/admin/auth/callback?next=/admin */\n redirectTo: string;\n /** Shown in the heading: \"Sign in to {siteName}\". */\n siteName: string;\n className?: string;\n}\n\ntype State = { kind: \"idle\" } | { kind: \"sending\" } | { kind: \"sent\"; email: string } | { kind: \"error\"; message: string; uninvited: boolean };\n\nexport const UNINVITED_MESSAGE =\n \"This email address isn't set up for this site yet. Ask the site owner to send you an invite.\";\n\nexport function isUninvitedError(message: string): boolean {\n return /signups? not allowed|not allowed|user not found|invalid login/i.test(message);\n}\n\nexport function MagicLinkForm({ url, anonKey, redirectTo, siteName, className }: MagicLinkFormProps) {\n const supabase = useMemo(() => createBrowserClient(url, anonKey), [url, anonKey]);\n const [email, setEmail] = useState(\"\");\n const [state, setState] = useState<State>({ kind: \"idle\" });\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n if (state.kind === \"sending\") return;\n const address = email.trim().toLowerCase();\n setState({ kind: \"sending\" });\n const { error } = await supabase.auth.signInWithOtp({\n email: address,\n options: { emailRedirectTo: redirectTo, shouldCreateUser: false },\n });\n if (error) {\n const uninvited = isUninvitedError(error.message);\n setState({ kind: \"error\", message: uninvited ? UNINVITED_MESSAGE : error.message, uninvited });\n return;\n }\n setState({ kind: \"sent\", email: address });\n };\n\n const root = [\"realiiz-form\", \"realiiz-signin\", className].filter(Boolean).join(\" \");\n\n if (state.kind === \"sent\") {\n return (\n <div className={root} data-realiiz-signin=\"sent\">\n <style>{FORM_CSS}</style>\n <h2 className=\"realiiz-signin__heading\">Check your email</h2>\n <p>\n We sent a sign-in link to <strong>{state.email}</strong>. It expires in an hour.\n </p>\n <button type=\"button\" className=\"realiiz-form__button\" onClick={() => setState({ kind: \"idle\" })}>\n Use a different address\n </button>\n </div>\n );\n }\n\n const sending = state.kind === \"sending\";\n const fieldError = state.kind === \"error\" && !state.uninvited ? state.message : null;\n\n return (\n <form className={root} onSubmit={submit} noValidate data-realiiz-signin=\"form\">\n <style>{FORM_CSS}</style>\n <h2 className=\"realiiz-signin__heading\">Sign in to {siteName}</h2>\n\n {state.kind === \"error\" && state.uninvited && (\n <div className=\"realiiz-form__alert\" role=\"alert\">{state.message}</div>\n )}\n\n <div className=\"realiiz-form__field\">\n <label className=\"realiiz-form__label\" htmlFor=\"realiiz-signin-email\">Email address</label>\n <input\n id=\"realiiz-signin-email\"\n className={[\"realiiz-form__control\", fieldError && \"realiiz-form__control--invalid\"].filter(Boolean).join(\" \")}\n type=\"email\"\n name=\"email\"\n autoComplete=\"email\"\n required\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n aria-invalid={fieldError ? true : undefined}\n aria-describedby={fieldError ? \"realiiz-signin-email-error\" : undefined}\n />\n {fieldError && (\n <div className=\"realiiz-form__error\" id=\"realiiz-signin-email-error\">{fieldError}</div>\n )}\n </div>\n\n <div className=\"realiiz-form__actions\">\n <button type=\"submit\" className=\"realiiz-form__button realiiz-form__button--primary\" disabled={sending || email.trim() === \"\"}>\n {sending ? \"Sending…\" : \"Send me a sign-in link\"}\n </button>\n </div>\n </form>\n );\n}\n","/**\n * SignOutButton — a plain POST form. No JavaScript needed, so it works before\n * hydration and inside a server component. The site's route (ADMIN-04) calls\n * signOut() from @realiizlabs/admin/auth and redirects.\n */\n\nexport interface SignOutButtonProps {\n /** Default \"/admin/auth/signout\". */\n actionPath?: string;\n className?: string;\n label?: string;\n}\n\nexport function SignOutButton({ actionPath = \"/admin/auth/signout\", className, label = \"Sign out\" }: SignOutButtonProps) {\n return (\n <form method=\"post\" action={actionPath} className={[\"realiiz-signout\", className].filter(Boolean).join(\" \")}>\n <button type=\"submit\" className=\"realiiz-form__button\">{label}</button>\n </form>\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { FORM_CSS } from '../chunk-FTD4WE3V.js';
2
+ import { FORM_CSS } from '../chunk-2GSYBARR.js';
3
3
  import { createBrowserClient } from '@supabase/ssr';
4
4
  import { useMemo, useState } from 'react';
5
5
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -23,6 +23,18 @@ var FORM_CSS = `
23
23
  .realiiz-form__control--textarea{min-height:110px;resize:vertical}
24
24
  .realiiz-form__control--body{min-height:280px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px}
25
25
  .realiiz-form__control--invalid{border-color:var(--_danger)}
26
+ .realiiz-select{position:relative}
27
+ .realiiz-select__btn{display:flex;align-items:center;justify-content:space-between;gap:10px;text-align:left;cursor:pointer;background:#fff}
28
+ .realiiz-select__btn svg{flex-shrink:0;color:var(--_muted);transition:transform .15s}
29
+ .realiiz-select__btn--open{border-color:var(--_accent);box-shadow:var(--_ring)}
30
+ .realiiz-select__btn--open svg{transform:rotate(180deg)}
31
+ .realiiz-select__btn:disabled{opacity:.6;cursor:default}
32
+ .realiiz-select__placeholder{color:var(--_muted)}
33
+ .realiiz-select__menu{position:absolute;left:0;right:0;top:calc(100% + 6px);margin:0;padding:6px 0;list-style:none;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius);box-shadow:0 8px 24px rgba(14,23,38,.14);max-height:260px;overflow:auto;z-index:40}
34
+ .realiiz-select__item{display:flex;align-items:center;gap:8px;padding:8px 12px;font-size:14px;color:var(--_fg);cursor:pointer}
35
+ .realiiz-select__item--active{background:var(--realiiz-form-hover,rgba(0,0,0,.05))}
36
+ .realiiz-select__item--selected{font-weight:600}
37
+ .realiiz-select__check{width:1em;flex-shrink:0;color:var(--_accent);font-weight:700}
26
38
  .realiiz-form__check{display:flex;align-items:center;gap:8px;font-weight:500}
27
39
  .realiiz-form__check input{width:18px;height:18px;margin:0}
28
40
  .realiiz-form__helper{display:flex;justify-content:space-between;gap:12px;font-size:12px;color:var(--_muted);margin-top:4px;min-height:1em}
@@ -110,5 +122,5 @@ var FORM_CSS = `
110
122
  `;
111
123
 
112
124
  export { FORM_CSS };
113
- //# sourceMappingURL=chunk-FTD4WE3V.js.map
114
- //# sourceMappingURL=chunk-FTD4WE3V.js.map
125
+ //# sourceMappingURL=chunk-2GSYBARR.js.map
126
+ //# sourceMappingURL=chunk-2GSYBARR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/forms-ui/styles.ts"],"names":[],"mappings":";AAMO,IAAM,QAAA,GAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","file":"chunk-2GSYBARR.js","sourcesContent":["/**\n * Theming hooks, same convention as BookingWidget: a root class, BEM elements,\n * and --realiiz-form-* custom properties with fallbacks so the form is usable\n * with zero host CSS and fully themeable with a dozen variables.\n */\n\nexport const FORM_CSS = `\n.realiiz-form{\n --_fg:var(--realiiz-form-fg,#111);\n --_muted:var(--realiiz-form-muted,#666);\n --_border:var(--realiiz-form-border,#cfcfcf);\n --_accent:var(--realiiz-form-accent,#111);\n --_accent-fg:var(--realiiz-form-accent-fg,#fff);\n --_danger:var(--realiiz-form-danger,#b3261e);\n --_radius:var(--realiiz-form-radius,6px);\n --_font:var(--realiiz-form-font,system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif);\n --_ring:var(--realiiz-form-focus-ring,0 0 0 3px rgba(0,0,0,.15));\n box-sizing:border-box;max-width:100%;color:var(--_fg);font-family:var(--_font);font-size:15px;line-height:1.4;\n}\n.realiiz-form *,.realiiz-form *::before,.realiiz-form *::after{box-sizing:inherit}\n.realiiz-form fieldset{border:0;margin:0 0 20px;padding:0;min-width:0}\n.realiiz-form legend{font-weight:600;font-size:13px;letter-spacing:.02em;text-transform:uppercase;color:var(--_muted);margin-bottom:12px;padding:0}\n.realiiz-form__field{display:block;margin:0 0 16px}\n.realiiz-form__label{display:block;font-weight:500;margin-bottom:6px}\n.realiiz-form__required{color:var(--_danger);margin-left:3px}\n.realiiz-form__control{display:block;width:100%;max-width:100%;font:inherit;color:inherit;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius);padding:9px 11px;min-height:40px}\n.realiiz-form__control:focus{outline:none;border-color:var(--_accent);box-shadow:var(--_ring)}\n.realiiz-form__control--textarea{min-height:110px;resize:vertical}\n.realiiz-form__control--body{min-height:280px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px}\n.realiiz-form__control--invalid{border-color:var(--_danger)}\n.realiiz-select{position:relative}\n.realiiz-select__btn{display:flex;align-items:center;justify-content:space-between;gap:10px;text-align:left;cursor:pointer;background:#fff}\n.realiiz-select__btn svg{flex-shrink:0;color:var(--_muted);transition:transform .15s}\n.realiiz-select__btn--open{border-color:var(--_accent);box-shadow:var(--_ring)}\n.realiiz-select__btn--open svg{transform:rotate(180deg)}\n.realiiz-select__btn:disabled{opacity:.6;cursor:default}\n.realiiz-select__placeholder{color:var(--_muted)}\n.realiiz-select__menu{position:absolute;left:0;right:0;top:calc(100% + 6px);margin:0;padding:6px 0;list-style:none;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius);box-shadow:0 8px 24px rgba(14,23,38,.14);max-height:260px;overflow:auto;z-index:40}\n.realiiz-select__item{display:flex;align-items:center;gap:8px;padding:8px 12px;font-size:14px;color:var(--_fg);cursor:pointer}\n.realiiz-select__item--active{background:var(--realiiz-form-hover,rgba(0,0,0,.05))}\n.realiiz-select__item--selected{font-weight:600}\n.realiiz-select__check{width:1em;flex-shrink:0;color:var(--_accent);font-weight:700}\n.realiiz-form__check{display:flex;align-items:center;gap:8px;font-weight:500}\n.realiiz-form__check input{width:18px;height:18px;margin:0}\n.realiiz-form__helper{display:flex;justify-content:space-between;gap:12px;font-size:12px;color:var(--_muted);margin-top:4px;min-height:1em}\n.realiiz-form__count{margin-left:auto;font-variant-numeric:tabular-nums}\n.realiiz-form__error{color:var(--_danger);font-size:13px;margin-top:4px}\n.realiiz-image{border:1px dashed var(--_border);border-radius:var(--_radius);padding:16px 18px;background:#fff;outline:none;transition:border-color .15s}\n.realiiz-image--over{border-color:var(--_accent);border-style:solid}\n.realiiz-image--invalid{border-color:var(--_danger)}\n.realiiz-image--busy{opacity:.7}\n.realiiz-image__empty{display:flex;align-items:center;gap:14px;flex-wrap:wrap;color:var(--_muted)}\n.realiiz-image__icon{flex-shrink:0;color:var(--_muted)}\n.realiiz-image__or{font-size:13px}\n.realiiz-image__has{display:flex;align-items:flex-start;gap:16px}\n.realiiz-image__thumb{display:block;max-height:160px;max-width:min(320px,55%);width:auto;object-fit:cover;border-radius:8px;border:1px solid var(--_border);background:#f6f8fa}\n.realiiz-image__meta{display:flex;flex-direction:column;gap:10px;min-width:0}\n.realiiz-image__detail{font-size:13px;color:var(--_muted);word-break:break-all}\n.realiiz-image__actions{display:flex;align-items:center;gap:14px}\n.realiiz-image__remove{font:inherit;font-size:13px;background:none;border:0;padding:0;color:var(--_muted);text-decoration:underline;text-underline-offset:3px;cursor:pointer}\n.realiiz-image__remove:hover{color:var(--_danger)}\n.realiiz-image__hint{font-size:12px;color:var(--_muted);margin-top:10px}\n.realiiz-image .realiiz-form__error{margin-top:8px}\n@media (max-width:720px){.realiiz-image__has{flex-direction:column}.realiiz-image__thumb{max-width:100%}}\n.realiiz-form__alert{border:1px solid var(--_danger);border-radius:var(--_radius);padding:12px 14px;margin:0 0 20px;color:var(--_danger)}\n.realiiz-form__alert ul{margin:6px 0 0;padding-left:18px}\n.realiiz-form__actions{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;margin-top:8px}\n.realiiz-form__help{text-decoration:underline dotted;text-decoration-color:color-mix(in srgb,currentColor 45%,transparent);text-underline-offset:4px;cursor:help}\n.realiiz-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n.realiiz-form__footer{max-width:920px}\n.realiiz-form__bar{display:flex;align-items:center;gap:10px;margin-top:16px;padding:12px 0;border-top:1px solid var(--_border);background:#fff}\n.realiiz-form__status{margin-right:auto;font-size:.85rem;color:var(--_muted)}\n.realiiz-form__bar[data-dirty] .realiiz-form__status{color:var(--_fg)}\n.realiiz-form__button{font:inherit;font-weight:600;border-radius:var(--_radius);padding:10px 16px;border:1px solid var(--_border);background:#fff;color:var(--_fg);cursor:pointer;min-height:40px}\n.realiiz-form__button--primary{background:var(--_accent);color:var(--_accent-fg);border-color:var(--_accent)}\n.realiiz-form__button:disabled{opacity:.6;cursor:default}\n.realiiz-md{--_md-head:#fafbfd;--_md-hover:#f4f8fd;--_md-hover-line:#bcd0ea;--_md-on:#eef4fb;--_md-tip:#1f2933;position:relative}\n.realiiz-md__mode{display:inline-flex;align-self:flex-start;width:max-content;gap:2px;padding:3px;background:color-mix(in srgb,var(--_border) 40%,transparent);border-radius:8px;margin-bottom:8px}\n.realiiz-md__mode button{font:inherit;font-size:.8rem;padding:5px 13px;border:0;border-radius:6px;background:transparent;color:var(--_muted);cursor:pointer}\n.realiiz-md__mode button[aria-selected=\"true\"]{background:#fff;color:var(--_fg);box-shadow:0 1px 2px rgba(0,0,0,.12)}\n.realiiz-md__panel{position:relative;z-index:0;display:flex;flex-direction:column;border:1px solid var(--_border);border-radius:10px;background:#fff;overflow:hidden}\n.realiiz-md__panel:focus-within{border-color:var(--_md-hover-line)}\n.realiiz-md__head{position:relative;z-index:5;display:flex;align-items:center;gap:2px;flex-wrap:wrap;padding:5px 7px;background:var(--_md-head);border-bottom:1px solid var(--_border);flex-shrink:0}\n.realiiz-md__tools{display:flex;align-items:center;gap:3px;flex-wrap:wrap}\n.realiiz-md__spacer{flex:1}\n.realiiz-md__head button{position:relative;min-width:31px;height:28px;padding:0 9px;display:inline-flex;align-items:center;justify-content:center;background:#fff;border:1px solid var(--_border);border-radius:6px;font-family:inherit;font-size:.82rem;color:var(--_fg);cursor:pointer;line-height:1}\n.realiiz-md__head button:hover:not(:disabled){border-color:var(--_md-hover-line);background:var(--_md-hover)}\n.realiiz-md__head button:active{background:var(--_md-on)}\n.realiiz-md__head button.on{background:var(--_md-on);border-color:var(--_accent);color:var(--_accent);font-weight:600}\n.realiiz-md__ico{width:15px;height:15px;display:block}\n.realiiz-md__dot{font-size:1.05rem;line-height:1}\n.realiiz-md__sep{width:1px;height:17px;background:var(--_border);margin:0 5px}\n.realiiz-md__insert{display:inline-flex;align-items:center;gap:3px;border-left:1px solid var(--_border);padding-left:8px;margin-left:6px}\n.realiiz-md__insert button{background:#f6f8fa;color:var(--_muted);padding:0;width:31px}\n.realiiz-md__insert button:hover{color:var(--_accent)}\n.realiiz-md__lab{font-size:.74rem;color:var(--_muted);margin-right:3px}\n.realiiz-md__head button[data-tip]::after{content:attr(data-tip);position:absolute;top:calc(100% + 6px);left:0;background:var(--_md-tip);color:#fff;font-size:.72rem;padding:4px 8px;border-radius:5px;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .12s;z-index:20}\n.realiiz-md__head button[data-tip]:hover::after,.realiiz-md__head button[data-tip]:focus-visible::after{opacity:1}\n.realiiz-md__expand[data-tip]::after{left:auto;right:0}\n.realiiz-md__tgwrap{position:relative;display:inline-flex}\n.realiiz-md__tgrid{position:absolute;top:calc(100% + 6px);left:0;background:#fff;border:1px solid var(--_border);border-radius:9px;padding:9px;box-shadow:0 10px 28px rgba(0,0,0,.14);z-index:7;display:block}\n.realiiz-md__tgcells{display:grid;grid-template-columns:repeat(6,17px);gap:3px}\n.realiiz-md__tgcells i{width:17px;height:15px;border:1px solid var(--_border);border-radius:2px;background:#fff;cursor:pointer;display:block}\n.realiiz-md__tgcells i.hot{background:#dbe9fb;border-color:var(--_accent)}\n.realiiz-md__tglab{display:block;margin-top:8px;font-size:.74rem;color:var(--_muted);text-align:center;white-space:nowrap}\n.realiiz-md .realiiz-md__ta{flex:1 1 auto;border:0;border-radius:0;resize:vertical;background:#fff;max-width:none;padding:16px 18px;line-height:1.65}\n.realiiz-md .realiiz-md__ta:focus{outline:none;box-shadow:none}\n.realiiz-md__preview{padding:20px 24px;background:#fff}\n.realiiz-md__note{padding:4px 2px}\n.realiiz-md--fs{position:fixed;inset:0;z-index:60;background:#fff;padding:14px 22px 22px;overflow:auto;display:flex;flex-direction:column}\n.realiiz-md--fs .realiiz-md__panel{flex:1;min-height:0}\n.realiiz-md--fs .realiiz-md__ta,.realiiz-md--fs .realiiz-md__preview{flex:1;min-height:0;overflow:auto;resize:none}\n.realiiz-prose{max-width:68ch;line-height:1.65}\n.realiiz-chips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;min-height:40px;padding:5px 8px;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius)}\n.realiiz-chips:focus-within{border-color:var(--_accent);box-shadow:var(--_ring)}\n.realiiz-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 9px;border:1px solid var(--_border);border-radius:999px;font-size:.8rem}\n.realiiz-chip button{font:inherit;line-height:1;width:18px;height:18px;border-radius:50%;border:0;background:transparent;color:var(--_muted);cursor:pointer}\n.realiiz-chips__input{flex:1;min-width:120px;border:0;background:transparent;font:inherit;color:inherit;outline:none;padding:4px}\n.realiiz-chips__count{margin-left:auto;color:var(--_muted);font-size:.75rem}\n.realiiz-gauge{display:inline-flex;align-items:center;gap:10px;font-size:.75rem;color:var(--_muted)}\n.realiiz-gauge__bar{position:relative;width:140px;height:6px;border-radius:3px;background:var(--_border);overflow:hidden}\n.realiiz-gauge__zone{position:absolute;top:0;bottom:0;background:rgba(21,128,61,.28)}\n.realiiz-gauge__fill{position:absolute;top:0;bottom:0;left:0;background:var(--_muted);border-radius:3px;transition:width .12s}\n.realiiz-gauge__text b{font-weight:600;color:inherit}\n.realiiz-gauge--ok{color:#15803d}.realiiz-gauge--ok .realiiz-gauge__fill{background:#15803d}\n.realiiz-gauge--over{color:var(--_danger)}.realiiz-gauge--over .realiiz-gauge__fill{background:var(--_danger)}\n`;\n"]}
@@ -137,7 +137,7 @@ function readMeta(schema) {
137
137
  const pick = (k) => typeof raw[k] === "string" ? raw[k] : void 0;
138
138
  const rec = raw.recommended;
139
139
  const recommended = Array.isArray(rec) && rec.length === 2 && rec.every((n) => typeof n === "number") ? [rec[0], rec[1]] : void 0;
140
- const INPUTS = ["text", "textarea", "date", "number", "boolean", "select", "tags", "image", "url"];
140
+ const INPUTS = ["text", "textarea", "date", "number", "boolean", "select", "tags", "image", "url", "time"];
141
141
  const input = typeof raw.input === "string" && INPUTS.includes(raw.input) ? raw.input : void 0;
142
142
  return {
143
143
  label: pick("label"),
@@ -236,6 +236,9 @@ function defineContentType(entry) {
236
236
  if (typeof entry.filename !== "function") {
237
237
  throw new TypeError(`${where}: "filename" must be a function (frontmatter) => string`);
238
238
  }
239
+ if (entry.slugFromFilename !== void 0 && typeof entry.slugFromFilename !== "function") {
240
+ throw new TypeError(`${where}: "slugFromFilename" must be a function (fileName) => string | null`);
241
+ }
239
242
  if (entry.body !== null && typeof entry.body !== "string") {
240
243
  throw new TypeError(`${where}: "body" must be a field name or null`);
241
244
  }
@@ -282,5 +285,5 @@ function navFromContentTypes(entries, opts = {}) {
282
285
  }
283
286
 
284
287
  export { defineContentType, navFromContentTypes, titlecase, walkSchema };
285
- //# sourceMappingURL=chunk-J6FI73PF.js.map
286
- //# sourceMappingURL=chunk-J6FI73PF.js.map
288
+ //# sourceMappingURL=chunk-JLR5K6RP.js.map
289
+ //# sourceMappingURL=chunk-JLR5K6RP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/forms/internals.ts","../src/forms/checks.ts","../src/forms/unwrap.ts","../src/forms/inputs.ts","../src/forms/labels.ts","../src/forms/walk.ts","../src/forms/registry.ts","../src/forms/nav.ts"],"names":[],"mappings":"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","file":"chunk-JLR5K6RP.js","sourcesContent":["/**\n * The slice of zod 4's `_zod.def` surface this module reads, typed loosely.\n *\n * Tested against zod 4.5.4. These are semi-public internals (the v4 \"core\"\n * shape), stable across 4.x so far but not covered by semver promises — hence\n * the peer-dep range and the fixture tests. No zod value is imported here.\n */\n\nexport interface ZodCheckDef {\n check?: string;\n format?: string;\n minimum?: number;\n maximum?: number;\n length?: number;\n value?: number;\n inclusive?: boolean;\n pattern?: RegExp;\n error?: string | ((issue: unknown) => string | { message?: string } | undefined);\n}\n\nexport interface ZodDef {\n type: string;\n shape?: Record<string, ZodNode>;\n innerType?: ZodNode;\n in?: ZodNode;\n out?: ZodNode;\n element?: ZodNode;\n entries?: Record<string, string | number>;\n checks?: Array<{ _zod: { def: ZodCheckDef } }>;\n coerce?: boolean;\n}\n\nexport interface ZodNode {\n _zod: { def: ZodDef };\n description?: string;\n}\n\n/** Narrow an unknown schema to the internal node shape, or throw a clear error. */\nexport function asNode(schema: unknown, what = \"schema\"): ZodNode {\n const n = schema as Partial<ZodNode> | null;\n if (!n || typeof n !== \"object\" || !n._zod?.def?.type) {\n throw new TypeError(`walkSchema: ${what} is not a zod 4 schema`);\n }\n return n as ZodNode;\n}\n\n/** Resolve a check's error to a plain string, if it has one. */\nexport function checkMessage(def: ZodCheckDef): string | undefined {\n const e = def.error;\n if (!e) return undefined;\n if (typeof e === \"string\") return e;\n const out = e({});\n if (typeof out === \"string\") return out;\n return out?.message;\n}\n","/**\n * checks[] → constraints + messages.\n *\n * Messages are keyed PER CHECK. The spike's walker wrote `out.message = …` on\n * every check, so a field with min and max kept only the max message and\n * showed the wrong error for a too-short value. Here each check kind gets its\n * own key; a renderer maps a failed issue to its message by that key.\n *\n * Unknown check kinds (e.g. a per-field `.refine`, which is `custom`) are kept\n * as a message when they carry one and otherwise skipped — never fatal.\n */\n\nimport type { Constraints, Messages } from \"./types\";\nimport type { ZodNode } from \"./internals\";\nimport { checkMessage } from \"./internals\";\n\nexport function readChecks(node: ZodNode): { constraints: Constraints; messages: Messages } {\n const constraints: Constraints = {};\n const messages: Messages = {};\n\n for (const c of node._zod.def.checks ?? []) {\n const d = c._zod.def;\n const msg = checkMessage(d);\n let key: string | undefined;\n\n switch (d.check) {\n case \"min_length\":\n constraints.min = d.minimum;\n key = \"min_length\";\n break;\n case \"max_length\":\n constraints.max = d.maximum;\n key = \"max_length\";\n break;\n case \"length_equals\":\n constraints.exact = d.length;\n key = \"length_equals\";\n break;\n case \"greater_than\":\n constraints.min = d.inclusive ? d.value : (d.value ?? 0) + 1;\n key = \"greater_than\";\n break;\n case \"less_than\":\n constraints.max = d.inclusive ? d.value : (d.value ?? 0) - 1;\n key = \"less_than\";\n break;\n case \"string_format\":\n if (d.format === \"regex\" && d.pattern) {\n constraints.pattern = d.pattern.source;\n constraints.format = \"regex\";\n key = \"regex\";\n } else if (d.format === \"url\" || d.format === \"email\") {\n constraints.format = d.format;\n key = d.format;\n } else {\n key = d.format;\n }\n break;\n case \"number_format\":\n if (d.format === \"safeint\" || d.format === \"int32\") {\n constraints.format = \"int\";\n key = \"int\";\n }\n break;\n case \"custom\":\n key = \"custom\";\n break;\n default:\n key = d.check;\n }\n\n if (key && msg) messages[key] = msg;\n }\n\n return { constraints, messages };\n}\n","/**\n * Peel wrapper types off a field until the real type is reached.\n *\n * optional / nullable / default → the field is not required.\n * pipe → follow `out` (older 4.x wrapped z.coerce.date in a pipe; 4.5 marks\n * the date itself with `coerce: true` — both land on the same node here).\n */\n\nimport type { ZodNode } from \"./internals\";\n\nexport interface Unwrapped {\n node: ZodNode;\n type: string;\n required: boolean;\n}\n\nexport function unwrap(start: ZodNode): Unwrapped {\n let node = start;\n let required = true;\n // Bounded so a malformed schema can't loop forever.\n for (let i = 0; i < 16; i++) {\n const def = node._zod.def;\n if (def.type === \"optional\" || def.type === \"nullable\" || def.type === \"default\") {\n required = false;\n if (!def.innerType) break;\n node = def.innerType;\n } else if (def.type === \"pipe\") {\n const next = def.out ?? def.in;\n if (!next) break;\n node = next;\n } else {\n break;\n }\n }\n return { node, type: node._zod.def.type, required };\n}\n","/**\n * zod type → InputKind, plus the extras some kinds carry (enum options, the\n * array item's constraints).\n *\n * Long strings become textareas by a simple rule: a max over 120 chars. That\n * is a heuristic, and the registry can't override it today — if a site needs\n * to, that is a one-line change here, not a per-site branch.\n */\n\nimport type { Constraints, InputKind, Messages } from \"./types\";\nimport type { ZodNode } from \"./internals\";\nimport { readChecks } from \"./checks\";\nimport { unwrap } from \"./unwrap\";\n\nconst TEXTAREA_MIN_MAX = 120;\n\nexport interface InputInfo {\n input: InputKind;\n constraints: Constraints;\n messages: Messages;\n options?: string[];\n}\n\nexport function inputFor(node: ZodNode): InputInfo {\n const def = node._zod.def;\n const { constraints, messages } = readChecks(node);\n\n switch (def.type) {\n case \"string\": {\n if (constraints.format === \"url\") return { input: \"url\", constraints, messages };\n const long = (constraints.max ?? 0) > TEXTAREA_MIN_MAX;\n return { input: long ? \"textarea\" : \"text\", constraints, messages };\n }\n case \"date\":\n return { input: \"date\", constraints, messages };\n case \"number\":\n case \"int\":\n return { input: \"number\", constraints, messages };\n case \"boolean\":\n return { input: \"boolean\", constraints, messages };\n case \"enum\":\n case \"literal\": {\n const options = Object.values(def.entries ?? {}).map(String);\n return { input: \"select\", constraints, messages, options };\n }\n case \"array\": {\n if (def.element) {\n const item = unwrap(def.element);\n const inner = readChecks(item.node);\n constraints.item = inner;\n }\n return { input: \"tags\", constraints, messages };\n }\n default:\n // Anything unrecognised (object, union, …) is presented as text so the\n // value can at least be carried; a renderer may choose to treat it as hidden.\n return { input: \"text\", constraints, messages };\n }\n}\n","/**\n * Labels and placeholders.\n *\n * Precedence (decided 2026-09-08):\n * label: registry.labels[name] → .meta({ label }) → .describe() → titlecase(name)\n * placeholder: registry.placeholders[name] → .meta({ placeholder }) → undefined\n *\n * The registry tier exists for schemas that can't be edited yet (5degrees\n * until its repo transfer). The meta tier is the intended home — one source of\n * truth beside the validation rules. Titlecase is the floor, and it is naive on\n * purpose: an acronym coming out as \"Rsvp url\" is the signal that a real label\n * is missing.\n *\n * Meta is read from zod's global registry via the schema's own `meta()` /\n * `description` accessors, so no zod value is imported here.\n */\n\nimport type { ContentTypeEntry, InputKind } from \"./types\";\n\ninterface MetaBearing {\n meta?: () => Record<string, unknown> | undefined;\n description?: string;\n}\n\ninterface FieldMeta {\n label?: string;\n placeholder?: string;\n description?: string;\n recommended?: [number, number];\n suffix?: string;\n help?: string;\n input?: InputKind;\n}\n\nexport function readMeta(schema: unknown): FieldMeta {\n const s = schema as MetaBearing;\n const raw = typeof s.meta === \"function\" ? (s.meta() ?? {}) : {};\n const pick = (k: keyof FieldMeta) => (typeof raw[k] === \"string\" ? (raw[k] as string) : undefined);\n const rec = raw.recommended;\n const recommended =\n Array.isArray(rec) && rec.length === 2 && rec.every((n) => typeof n === \"number\") ? ([rec[0], rec[1]] as [number, number]) : undefined;\n const INPUTS: InputKind[] = [\"text\", \"textarea\", \"date\", \"number\", \"boolean\", \"select\", \"tags\", \"image\", \"url\", \"time\"];\n const input = typeof raw.input === \"string\" && (INPUTS as string[]).includes(raw.input) ? (raw.input as InputKind) : undefined;\n return {\n label: pick(\"label\"),\n placeholder: pick(\"placeholder\"),\n description: pick(\"description\") ?? (typeof s.description === \"string\" ? s.description : undefined),\n recommended,\n suffix: pick(\"suffix\"),\n help: pick(\"help\"),\n input,\n };\n}\n\nexport function inputOverrideFor(\n name: string,\n schema: unknown,\n entry?: Pick<ContentTypeEntry, \"inputs\">,\n): InputKind | undefined {\n return entry?.inputs?.[name] ?? readMeta(schema).input;\n}\n\nexport function recommendedFor(\n name: string,\n schema: unknown,\n entry?: Pick<ContentTypeEntry, \"recommended\">,\n): [number, number] | undefined {\n return entry?.recommended?.[name] ?? readMeta(schema).recommended;\n}\n\nexport function titlecase(name: string): string {\n const words = name\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[_-]+/g, \" \")\n .toLowerCase()\n .trim();\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\nexport function labelFor(name: string, schema: unknown, entry?: Pick<ContentTypeEntry, \"labels\">): string {\n const fromRegistry = entry?.labels?.[name];\n if (fromRegistry) return fromRegistry;\n const meta = readMeta(schema);\n return meta.label ?? meta.description ?? titlecase(name);\n}\n\nexport function placeholderFor(\n name: string,\n schema: unknown,\n entry?: Pick<ContentTypeEntry, \"placeholders\">,\n): string | undefined {\n return entry?.placeholders?.[name] ?? readMeta(schema).placeholder;\n}\n\nexport function helpFor(name: string, schema: unknown, entry?: Pick<ContentTypeEntry, \"help\">): string | undefined {\n return entry?.help?.[name] ?? readMeta(schema).help;\n}\n","/**\n * walkSchema — a zod object schema (+ optional registry entry) → FieldSpec[].\n *\n * Synchronous and pure. Reads the schema's shape and checks; never parses a\n * value, never calls an options resolver, never imports zod at runtime.\n *\n * Roles from the registry override the schema-derived input kind: a field the\n * entry names as an image is `role: \"image\"` even though zod sees a string.\n * Hidden fields are still emitted so a renderer can carry their values through.\n */\n\nimport type { ContentTypeEntry, FieldRole, FieldSpec } from \"./types\";\nimport type { ZodNode } from \"./internals\";\nimport { asNode } from \"./internals\";\nimport { inputFor } from \"./inputs\";\nimport { helpFor, inputOverrideFor, labelFor, placeholderFor, readMeta, recommendedFor } from \"./labels\";\nimport { unwrap } from \"./unwrap\";\n\ntype Entry = Partial<Omit<ContentTypeEntry, \"schema\" | \"filename\" | \"id\" | \"label\" | \"folder\">>;\n\nexport function walkSchema(schema: unknown, entry: Entry = {}): FieldSpec[] {\n const root = asNode(schema);\n const shape = shapeOf(root);\n const names = Object.keys(shape);\n\n const specs = names.map((name): FieldSpec => {\n const raw = shape[name];\n const { node, required } = unwrap(raw);\n const info = inputFor(node);\n const role = roleFor(name, entry);\n\n return {\n name,\n label: labelFor(name, raw, entry),\n input: role === \"image\" ? \"image\" : (inputOverrideFor(name, raw, entry) ?? info.input),\n required,\n constraints: info.constraints,\n messages: info.messages,\n placeholder: placeholderFor(name, raw, entry),\n recommended: recommendedFor(name, raw, entry),\n suffix: readMeta(raw).suffix,\n help: helpFor(name, raw, entry),\n order: 0,\n role,\n options: entry.options?.[name] ?? info.options,\n };\n });\n\n return applyOrder(specs, entry.order ?? []);\n}\n\n/** `.strict()` and object-level `.refine()` both leave `shape` on the object def. */\nfunction shapeOf(root: ZodNode): Record<string, ZodNode> {\n let node = root;\n for (let i = 0; i < 8 && !node._zod.def.shape; i++) {\n const def = node._zod.def;\n const next = def.innerType ?? def.in;\n if (!next) break;\n node = next;\n }\n const shape = node._zod.def.shape;\n if (!shape) throw new TypeError(`walkSchema: expected an object schema, got \"${root._zod.def.type}\"`);\n return shape;\n}\n\nfunction roleFor(name: string, entry: Entry): FieldRole {\n if (entry.hidden?.includes(name)) return \"hidden\";\n if (entry.body === name) return \"body\";\n if (entry.images?.includes(name)) return \"image\";\n return \"field\";\n}\n\n/** Named fields first in the given order; the rest keep schema key order. */\nfunction applyOrder(specs: FieldSpec[], order: string[]): FieldSpec[] {\n const rank = new Map(order.map((n, i) => [n, i]));\n const named = specs.filter((s) => rank.has(s.name)).sort((a, b) => rank.get(a.name)! - rank.get(b.name)!);\n const rest = specs.filter((s) => !rank.has(s.name));\n return [...named, ...rest].map((s, i) => ({ ...s, order: i }));\n}\n","/**\n * defineContentType — validate a registry entry against the schema it describes.\n *\n * Validation is hand-rolled rather than a zod schema on purpose: this module\n * must not import zod at runtime (the host's instance is the only one that\n * should exist). The checks are small and the errors name the bad key.\n */\n\nimport type { ZodType } from \"zod\";\nimport type { ContentTypeEntry } from \"./types\";\nimport { asNode } from \"./internals\";\n\nexport function defineContentType<S extends ZodType>(entry: ContentTypeEntry<S>): ContentTypeEntry<S> {\n const where = `defineContentType(\"${entry.id}\")`;\n\n for (const key of [\"id\", \"label\", \"folder\"] as const) {\n if (typeof entry[key] !== \"string\" || entry[key].length === 0) {\n throw new TypeError(`${where}: \"${key}\" must be a non-empty string`);\n }\n }\n if (typeof entry.filename !== \"function\") {\n throw new TypeError(`${where}: \"filename\" must be a function (frontmatter) => string`);\n }\n if (entry.slugFromFilename !== undefined && typeof entry.slugFromFilename !== \"function\") {\n throw new TypeError(`${where}: \"slugFromFilename\" must be a function (fileName) => string | null`);\n }\n if (entry.body !== null && typeof entry.body !== \"string\") {\n throw new TypeError(`${where}: \"body\" must be a field name or null`);\n }\n\n const root = asNode(entry.schema, `${where}: schema`);\n const shape = findShape(root);\n const known = new Set(Object.keys(shape));\n\n const check = (list: string[] | undefined, key: string) => {\n for (const name of list ?? []) {\n if (!known.has(name)) throw new TypeError(`${where}: ${key} names \"${name}\", which is not a field of the schema`);\n }\n };\n\n if (entry.body !== null) check([entry.body], \"body\");\n check(entry.images, \"images\");\n check(entry.order, \"order\");\n check(entry.hidden, \"hidden\");\n check(Object.keys(entry.labels ?? {}), \"labels\");\n check(Object.keys(entry.placeholders ?? {}), \"placeholders\");\n check(Object.keys(entry.recommended ?? {}), \"recommended\");\n check(Object.keys(entry.inputs ?? {}), \"inputs\");\n check(Object.keys(entry.help ?? {}), \"help\");\n check(Object.keys(entry.options ?? {}), \"options\");\n for (const g of entry.groups ?? []) {\n if (typeof g.label !== \"string\" || g.label.length === 0) throw new TypeError(`${where}: every group needs a label`);\n check(g.fields, `groups[\"${g.label}\"]`);\n }\n\n return entry;\n}\n\nfunction findShape(root: ReturnType<typeof asNode>): Record<string, unknown> {\n let node = root;\n for (let i = 0; i < 8 && !node._zod.def.shape; i++) {\n const next = node._zod.def.innerType ?? node._zod.def.in;\n if (!next) break;\n node = next;\n }\n if (!node._zod.def.shape) throw new TypeError(\"defineContentType: schema must be a zod object\");\n return node._zod.def.shape;\n}\n","/**\n * navFromContentTypes — the sidebar derives from the registry.\n *\n * Adding a content type to a site (one defineContentType entry) puts it in\n * the nav with no shell change. Pure; lives in /forms so the server layout\n * can compute it without importing the client bundle.\n */\n\nimport type { ContentTypeEntry } from \"./types\";\n\nexport interface NavEntry {\n id: string;\n label: string;\n href: string;\n icon: string;\n}\n\nexport function navFromContentTypes(\n entries: Record<string, ContentTypeEntry> | ContentTypeEntry[],\n opts: { basePath?: string } = {},\n): NavEntry[] {\n const base = (opts.basePath ?? \"/admin\").replace(/\\/+$/, \"\");\n const list = Array.isArray(entries) ? entries : Object.values(entries);\n return list.map((e) => ({ id: e.id, label: e.label, href: `${base}/${e.id}`, icon: e.id }));\n}\n"]}
@@ -0,0 +1,226 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+
5
+ // src/events/schema.ts
6
+ var EVENT_GROUPS = ["venues", "tickets", "appearances"];
7
+ var venuesShape = {
8
+ venue: zod.z.string().min(1, "pick a venue").meta({ label: "Venue", help: "Where this happens. Venues are kept in their own list so the address is typed once." })
9
+ };
10
+ var ticketsShape = {
11
+ rsvpUrl: zod.z.string().url("the RSVP link must be a full web address, starting with https://").optional().meta({ label: "RSVP or ticket link", placeholder: "https://\u2026", help: "Where people go to sign up or buy a ticket. Leave blank if there is nothing to book." }),
12
+ capacity: zod.z.number().int("capacity must be a whole number").positive("capacity must be more than zero").optional().meta({ label: "Capacity", help: "How many people can come. Leave blank if there is no limit." }),
13
+ closed: zod.z.boolean().optional().meta({ label: "Sign-ups closed", help: "Tick this to stop taking sign-ups while still showing the event." }),
14
+ private: zod.z.boolean().optional().meta({ label: "Private event", help: "Invited guests only. The event still shows, but nobody can sign up from the website." })
15
+ };
16
+ var appearancesShape = {
17
+ host: zod.z.string().min(1, "host must not be empty when present").optional().meta({ label: "Hosted or published by", placeholder: "e.g. The SoundPlex, or the name of the podcast", help: "The organisation, venue, podcast or publication behind this appearance." }),
18
+ recordingUrl: zod.z.string().url("the recording link must be a full web address, starting with https://").optional().meta({ label: "Recording link", placeholder: "https://\u2026", help: "A video or audio recording to watch or listen to afterwards \u2014 YouTube, Spotify, the episode page." }),
19
+ slidesUrl: zod.z.string().url("the slides link must be a full web address, starting with https://").optional().meta({ label: "Slides link", placeholder: "https://\u2026", help: "Where the slides live, if you want to share them." })
20
+ };
21
+ var GROUP_SHAPES = {
22
+ venues: venuesShape,
23
+ tickets: ticketsShape,
24
+ appearances: appearancesShape
25
+ };
26
+
27
+ // src/events/zones.ts
28
+ var ZONES = ["Eastern", "Central", "Mountain", "Arizona", "Pacific", "Alaska", "Hawaii"];
29
+ var IANA = {
30
+ Eastern: "America/New_York",
31
+ Central: "America/Chicago",
32
+ Mountain: "America/Denver",
33
+ Arizona: "America/Phoenix",
34
+ Pacific: "America/Los_Angeles",
35
+ Alaska: "America/Anchorage",
36
+ Hawaii: "Pacific/Honolulu"
37
+ };
38
+ function zoneToIana(zone) {
39
+ return IANA[zone];
40
+ }
41
+ function isZone(value) {
42
+ return typeof value === "string" && ZONES.includes(value);
43
+ }
44
+
45
+ // src/events/schema.ts
46
+ var DEFAULT_KINDS = ["talk", "panel", "workshop", "webinar", "podcast", "interview", "article"];
47
+ var OTHER_KIND = "other";
48
+ var SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
49
+ var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
50
+ var TIME_RE = /^([01]\d|2[0-3]):[0-5]\d$/;
51
+ var MESSAGES = {
52
+ date: "that date doesn\u2019t exist \u2014 check the month has that many days",
53
+ time: "use a 24-hour time like 19:00",
54
+ endTime: "add a start time first",
55
+ heroImageAlt: "describe the picture so screen readers and Google can read it",
56
+ kindLabel: "say what kind of event this is"
57
+ };
58
+ function realDate(value) {
59
+ const [y, m, d] = value.split("-").map(Number);
60
+ const dt = new Date(Date.UTC(y, m - 1, d));
61
+ return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;
62
+ }
63
+ var time = (label, help) => zod.z.string().regex(TIME_RE, MESSAGES.time).optional().meta({ label, help, input: "time" });
64
+ function coreShape(kinds) {
65
+ const kindValues = [...kinds, OTHER_KIND];
66
+ return {
67
+ title: zod.z.string().min(1, "give the event a title").meta({ label: "Title", placeholder: "What it's called", help: "The headline people see on the page and in the list." }),
68
+ slug: zod.z.string().min(1, "slug is required").regex(SLUG_RE, "slug must be lowercase words joined by hyphens, e.g. ai-talk-soundplex").meta({ label: "Web address (slug)", placeholder: "e.g. ai-talk-soundplex", help: "The last part of the link. Lowercase words joined by hyphens, no spaces." }),
69
+ summary: zod.z.string().min(1, "write a one-line summary").max(200, "keep the summary under 200 characters").meta({ label: "One-line summary", input: "textarea", help: "One or two sentences shown in the list. The longer description goes in the body below." }),
70
+ kind: zod.z.enum(kindValues).optional().meta({ label: "What kind of event", help: "Pick the closest. Choose \u201Cother\u201D to type your own." }),
71
+ kindLabel: zod.z.string().min(1, MESSAGES.kindLabel).max(40, "keep the custom kind under 40 characters").optional().meta({ label: "Custom kind", placeholder: "e.g. Fireside chat", help: "Only used when the kind is \u201Cother\u201D." }),
72
+ date: zod.z.string().regex(DATE_RE, "date must be written as YYYY-MM-DD, e.g. 2026-09-28").refine(realDate, { message: MESSAGES.date }).meta({ label: "Date", input: "date", help: "The day it happens. For a podcast or article, the day it comes out." }),
73
+ startTime: time("Start time", "Leave blank for an all-day item or something without a set time."),
74
+ endTime: time("End time", "Optional. Needs a start time."),
75
+ timezone: zod.z.enum(ZONES).optional().meta({ label: "Time zone", help: "Leave blank for the site's usual zone." }),
76
+ location: zod.z.string().min(1, "location must not be empty when present").optional().meta({ label: "Where", placeholder: "e.g. The SoundPlex, Pennsauken, NJ \u2014 or Online", help: "A place name and town, or \u201COnline\u201D. Shown under the title." }),
77
+ url: zod.z.string().url("the link must be a full web address, starting with https://").optional().meta({ label: "Link for details", placeholder: "https://\u2026", help: "The event's own page, if it has one." }),
78
+ heroImage: zod.z.string().min(1, "heroImage must be a path when present").optional().meta({ label: "Picture", help: "Optional. Choose a picture and we size it for the web." }),
79
+ heroImageAlt: zod.z.string().min(1, MESSAGES.heroImageAlt).optional().meta({ label: "Picture description", placeholder: "What the picture shows", help: "A sentence describing the picture, for screen readers and Google Images." }),
80
+ ogImage: zod.z.string().min(1, "ogImage must be a path when present").optional().meta({ label: "Social share image", help: "Shown when someone shares the link. Leave blank to reuse the picture." }),
81
+ cancelled: zod.z.boolean().optional().meta({ label: "Cancelled", help: "Keeps the event on the page, marked cancelled." }),
82
+ cancelledNote: zod.z.string().max(300, "keep the note under 300 characters").optional().meta({ label: "Cancellation note", placeholder: "e.g. Postponed \u2014 new date coming soon", help: "A short line shown with the cancelled event." }),
83
+ rescheduledTo: zod.z.string().regex(SLUG_RE, "rescheduledTo must be the web address (slug) of the replacement event").optional().meta({ label: "Moved to", placeholder: "the slug of the new event", help: "If this moved to a new date, the web address of the replacement." }),
84
+ previousDate: zod.z.string().regex(DATE_RE, "previousDate must be YYYY-MM-DD").optional().meta({ label: "Previous date", help: "If this event moved, the date it was originally on." })
85
+ };
86
+ }
87
+ function eventSchema(options = {}) {
88
+ const kinds = options.kinds ?? DEFAULT_KINDS;
89
+ const groups = (options.with ?? []).filter((g) => EVENT_GROUPS.includes(g));
90
+ const shape = { ...coreShape(kinds), ...Object.assign({}, ...groups.map((g) => GROUP_SHAPES[g])) };
91
+ const schema = zod.z.object(shape).strict().refine((d) => !d.endTime || !!d.startTime, { message: MESSAGES.endTime, path: ["endTime"] }).refine((d) => !d.heroImage || !!d.heroImageAlt, { message: MESSAGES.heroImageAlt, path: ["heroImageAlt"] }).refine((d) => d.kind !== OTHER_KIND || !!d.kindLabel, { message: MESSAGES.kindLabel, path: ["kindLabel"] }).refine((d) => d.kind === OTHER_KIND || !d.kindLabel, { message: "a custom kind is only used when the kind is \u201Cother\u201D", path: ["kindLabel"] });
92
+ return schema;
93
+ }
94
+ function kindOf(fm) {
95
+ if (fm.kind === OTHER_KIND) return fm.kindLabel?.trim() || null;
96
+ if (!fm.kind) return null;
97
+ return fm.kind.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
98
+ }
99
+ function eventFilename(fm) {
100
+ return `${String(fm.date)}-${String(fm.slug)}.mdx`;
101
+ }
102
+ function slugFromEventFilename(fileName) {
103
+ const m = /^\d{4}-\d{2}-\d{2}-([a-z0-9]+(?:-[a-z0-9]+)*)\.mdx$/.exec(fileName);
104
+ return m ? m[1] : null;
105
+ }
106
+ function slugFilename(fm) {
107
+ return `${String(fm.slug)}.mdx`;
108
+ }
109
+
110
+ // src/events/when.ts
111
+ function zoneFor(fm, opts) {
112
+ return isZone(fm.timezone) ? zoneToIana(fm.timezone) : opts.defaultZone;
113
+ }
114
+ function offsetAt(instant, zone) {
115
+ const parts = new Intl.DateTimeFormat("en-US", {
116
+ timeZone: zone,
117
+ hourCycle: "h23",
118
+ year: "numeric",
119
+ month: "2-digit",
120
+ day: "2-digit",
121
+ hour: "2-digit",
122
+ minute: "2-digit",
123
+ second: "2-digit"
124
+ }).formatToParts(instant);
125
+ const n = (t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
126
+ const asUtc = Date.UTC(n("year"), n("month") - 1, n("day"), n("hour"), n("minute"), n("second"));
127
+ return asUtc - instant.getTime();
128
+ }
129
+ function zonedInstant(date, hhmm, zone) {
130
+ const [y, m, d] = date.split("-").map(Number);
131
+ const [h, min] = hhmm.split(":").map(Number);
132
+ const wall = Date.UTC(y, m - 1, d, h, min);
133
+ let guess = wall - offsetAt(new Date(wall), zone);
134
+ guess = wall - offsetAt(new Date(guess), zone);
135
+ return new Date(guess);
136
+ }
137
+ function eventWhen(fm, opts) {
138
+ const zone = zoneFor(fm, opts);
139
+ if (!fm.startTime) {
140
+ return { start: zonedInstant(fm.date, "00:00", zone), end: null, zone, allDay: true };
141
+ }
142
+ const start = zonedInstant(fm.date, fm.startTime, zone);
143
+ const end = fm.endTime ? zonedInstant(fm.date, fm.endTime, zone) : null;
144
+ return { start, end, zone, allDay: false };
145
+ }
146
+ function endOfDay(when) {
147
+ const next = new Date(when.start.getTime() + 36 * 36e5);
148
+ const ymd = new Intl.DateTimeFormat("en-CA", { timeZone: when.zone, year: "numeric", month: "2-digit", day: "2-digit" }).format(next);
149
+ return zonedInstant(ymd, "00:00", when.zone);
150
+ }
151
+ function endsAt(when) {
152
+ if (when.allDay) return endOfDay(when);
153
+ return when.end ?? when.start;
154
+ }
155
+ function formatWhen(when, opts = {}) {
156
+ const locale = opts.locale ?? "en-US";
157
+ const day = new Intl.DateTimeFormat(locale, { timeZone: when.zone, weekday: "short", month: "short", day: "numeric", year: "numeric" }).format(when.start);
158
+ if (when.allDay) return day;
159
+ const clock = (d) => new Intl.DateTimeFormat(locale, { timeZone: when.zone, hour: "numeric", minute: "2-digit", hour12: true }).format(d).toLowerCase();
160
+ const zoneName = new Intl.DateTimeFormat(locale, { timeZone: when.zone, timeZoneName: "short" }).formatToParts(when.start).find((p) => p.type === "timeZoneName")?.value ?? "";
161
+ if (!when.end) return `${day} \xB7 ${clock(when.start)} ${zoneName}`.trim();
162
+ const s = clock(when.start);
163
+ const e = clock(when.end);
164
+ const [sTime, sMer] = s.split(" ");
165
+ const [, eMer] = e.split(" ");
166
+ const range = sMer === eMer ? `${sTime}\u2013${e}` : `${s}\u2013${e}`;
167
+ return `${day} \xB7 ${range} ${zoneName}`.trim();
168
+ }
169
+ function dayIn(instant, zone) {
170
+ return new Intl.DateTimeFormat("en-CA", { timeZone: zone, year: "numeric", month: "2-digit", day: "2-digit" }).format(instant);
171
+ }
172
+
173
+ // src/events/status.ts
174
+ function eventStatus(fm, now, opts) {
175
+ if (fm.cancelled) return "cancelled";
176
+ if (fm.rescheduledTo) return "rescheduled";
177
+ const when = eventWhen(fm, opts);
178
+ if (endsAt(when).getTime() < now.getTime()) return "past";
179
+ if (dayIn(when.start, when.zone) === dayIn(now, when.zone)) return "today";
180
+ return "upcoming";
181
+ }
182
+ function splitEvents(items, now, opts) {
183
+ const stamped = items.map((fm) => ({ fm, when: eventWhen(fm, opts) }));
184
+ const over = (x) => endsAt(x.when).getTime() < now.getTime();
185
+ const upcoming = stamped.filter((x) => !over(x)).sort((a, b) => a.when.start.getTime() - b.when.start.getTime());
186
+ const past = stamped.filter(over).sort((a, b) => b.when.start.getTime() - a.when.start.getTime());
187
+ return { upcoming: upcoming.map((x) => x.fm), past: past.map((x) => x.fm) };
188
+ }
189
+
190
+ // src/events/registry.ts
191
+ function eventRegistryDefaults(options = {}) {
192
+ const on = new Set(options.with ?? []);
193
+ const where = on.has("venues") ? "venue" : "location";
194
+ const order = ["title", "slug", "summary", "kind", "kindLabel", "date", "startTime", "endTime", "timezone", where, "url"];
195
+ if (on.has("venues")) order.push("location");
196
+ const groups = [];
197
+ if (on.has("tickets")) groups.push({ label: "Tickets & RSVP", fields: ["rsvpUrl", "capacity", "closed", "private"] });
198
+ if (on.has("appearances")) groups.push({ label: "Appearance details", fields: ["host", "recordingUrl", "slidesUrl"] });
199
+ groups.push({ label: "Pictures", fields: ["heroImage", "heroImageAlt", "ogImage"] });
200
+ groups.push({ label: "Changes", fields: ["cancelled", "cancelledNote", "rescheduledTo", "previousDate"] });
201
+ return { order, groups, images: ["heroImage", "ogImage"], inputs: {} };
202
+ }
203
+
204
+ exports.DEFAULT_KINDS = DEFAULT_KINDS;
205
+ exports.EVENT_GROUPS = EVENT_GROUPS;
206
+ exports.MESSAGES = MESSAGES;
207
+ exports.OTHER_KIND = OTHER_KIND;
208
+ exports.ZONES = ZONES;
209
+ exports.dayIn = dayIn;
210
+ exports.endsAt = endsAt;
211
+ exports.eventFilename = eventFilename;
212
+ exports.eventRegistryDefaults = eventRegistryDefaults;
213
+ exports.eventSchema = eventSchema;
214
+ exports.eventStatus = eventStatus;
215
+ exports.eventWhen = eventWhen;
216
+ exports.formatWhen = formatWhen;
217
+ exports.isZone = isZone;
218
+ exports.kindOf = kindOf;
219
+ exports.slugFilename = slugFilename;
220
+ exports.slugFromEventFilename = slugFromEventFilename;
221
+ exports.splitEvents = splitEvents;
222
+ exports.zoneFor = zoneFor;
223
+ exports.zoneToIana = zoneToIana;
224
+ exports.zonedInstant = zonedInstant;
225
+ //# sourceMappingURL=index.cjs.map
226
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/events/groups.ts","../../src/events/zones.ts","../../src/events/schema.ts","../../src/events/when.ts","../../src/events/status.ts","../../src/events/registry.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The optional field groups a site can switch on. Each is a zod shape fragment\n * merged into the core by eventSchema; nothing here knows about the others.\n *\n * zod is imported directly: it is external in tsup and a peer dependency, so\n * this resolves to the host site's copy — the same instance its own schemas use.\n */\n\nimport { z } from \"zod\";\n\nexport const EVENT_GROUPS = [\"venues\", \"tickets\", \"appearances\"] as const;\nexport type EventGroup = (typeof EVENT_GROUPS)[number];\n\n/** A reference to a venues collection. The SITE resolves the options (registry `options.venue`). */\nexport const venuesShape = {\n venue: z.string().min(1, \"pick a venue\")\n .meta({ label: \"Venue\", help: \"Where this happens. Venues are kept in their own list so the address is typed once.\" }),\n};\n\nexport const ticketsShape = {\n rsvpUrl: z.string().url(\"the RSVP link must be a full web address, starting with https://\").optional()\n .meta({ label: \"RSVP or ticket link\", placeholder: \"https://…\", help: \"Where people go to sign up or buy a ticket. Leave blank if there is nothing to book.\" }),\n capacity: z.number().int(\"capacity must be a whole number\").positive(\"capacity must be more than zero\").optional()\n .meta({ label: \"Capacity\", help: \"How many people can come. Leave blank if there is no limit.\" }),\n closed: z.boolean().optional()\n .meta({ label: \"Sign-ups closed\", help: \"Tick this to stop taking sign-ups while still showing the event.\" }),\n private: z.boolean().optional()\n .meta({ label: \"Private event\", help: \"Invited guests only. The event still shows, but nobody can sign up from the website.\" }),\n};\n\nexport const appearancesShape = {\n host: z.string().min(1, \"host must not be empty when present\").optional()\n .meta({ label: \"Hosted or published by\", placeholder: \"e.g. The SoundPlex, or the name of the podcast\", help: \"The organisation, venue, podcast or publication behind this appearance.\" }),\n recordingUrl: z.string().url(\"the recording link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Recording link\", placeholder: \"https://…\", help: \"A video or audio recording to watch or listen to afterwards — YouTube, Spotify, the episode page.\" }),\n slidesUrl: z.string().url(\"the slides link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Slides link\", placeholder: \"https://…\", help: \"Where the slides live, if you want to share them.\" }),\n};\n\nexport const GROUP_SHAPES = {\n venues: venuesShape,\n tickets: ticketsShape,\n appearances: appearancesShape,\n} as const;\n","/**\n * Time zones a client can pick from — friendly names, because \"America/Phoenix\"\n * means nothing to someone booking a talk. zoneToIana turns them back into what\n * Intl needs. US-only for now; extending the list is the whole change.\n */\n\nexport const ZONES = [\"Eastern\", \"Central\", \"Mountain\", \"Arizona\", \"Pacific\", \"Alaska\", \"Hawaii\"] as const;\nexport type Zone = (typeof ZONES)[number];\n\nconst IANA: Record<Zone, string> = {\n Eastern: \"America/New_York\",\n Central: \"America/Chicago\",\n Mountain: \"America/Denver\",\n Arizona: \"America/Phoenix\",\n Pacific: \"America/Los_Angeles\",\n Alaska: \"America/Anchorage\",\n Hawaii: \"Pacific/Honolulu\",\n};\n\nexport function zoneToIana(zone: Zone): string {\n return IANA[zone];\n}\n\nexport function isZone(value: unknown): value is Zone {\n return typeof value === \"string\" && (ZONES as readonly string[]).includes(value);\n}\n","/**\n * eventSchema — one events model for every site, assembled from a core plus the\n * groups a site switches on. Labels and help live here as .meta() so the form\n * needs no registry overrides.\n *\n * Time is stored the way a person wrote it — a date, a wall-clock time, a zone —\n * never a UTC instant. That is what survives a hand edit on GitHub. when.ts turns\n * it into instants at render time.\n */\n\nimport { z } from \"zod\";\nimport { EVENT_GROUPS, GROUP_SHAPES, type EventGroup } from \"./groups\";\nimport { ZONES, type Zone } from \"./zones\";\n\nexport const DEFAULT_KINDS = [\"talk\", \"panel\", \"workshop\", \"webinar\", \"podcast\", \"interview\", \"article\"] as const;\nexport type DefaultKind = (typeof DEFAULT_KINDS)[number];\n\n/** Always accepted, whatever the site's list: unlocks the free-text kindLabel. */\nexport const OTHER_KIND = \"other\";\n\nexport const SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nexport const TIME_RE = /^([01]\\d|2[0-3]):[0-5]\\d$/;\n\nexport const MESSAGES = {\n date: \"that date doesn’t exist — check the month has that many days\",\n time: \"use a 24-hour time like 19:00\",\n endTime: \"add a start time first\",\n heroImageAlt: \"describe the picture so screen readers and Google can read it\",\n kindLabel: \"say what kind of event this is\",\n} as const;\n\nexport interface EventSchemaOptions<G extends EventGroup = never, K extends string = DefaultKind> {\n /** Optional groups to switch on. */\n with?: readonly G[];\n /** The site's own list of kinds; \"other\" is always added. Defaults to DEFAULT_KINDS. */\n kinds?: readonly [K, ...K[]];\n}\n\nfunction realDate(value: string): boolean {\n const [y, m, d] = value.split(\"-\").map(Number);\n const dt = new Date(Date.UTC(y, m - 1, d));\n return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;\n}\n\nconst time = (label: string, help: string) =>\n z.string().regex(TIME_RE, MESSAGES.time).optional().meta({ label, help, input: \"time\" });\n\nfunction coreShape<K extends string>(kinds: readonly [K, ...K[]]) {\n const kindValues = [...kinds, OTHER_KIND] as [string, ...string[]];\n return {\n title: z.string().min(1, \"give the event a title\")\n .meta({ label: \"Title\", placeholder: \"What it's called\", help: \"The headline people see on the page and in the list.\" }),\n slug: z.string().min(1, \"slug is required\").regex(SLUG_RE, \"slug must be lowercase words joined by hyphens, e.g. ai-talk-soundplex\")\n .meta({ label: \"Web address (slug)\", placeholder: \"e.g. ai-talk-soundplex\", help: \"The last part of the link. Lowercase words joined by hyphens, no spaces.\" }),\n summary: z.string().min(1, \"write a one-line summary\").max(200, \"keep the summary under 200 characters\")\n .meta({ label: \"One-line summary\", input: \"textarea\", help: \"One or two sentences shown in the list. The longer description goes in the body below.\" }),\n kind: z.enum(kindValues).optional()\n .meta({ label: \"What kind of event\", help: \"Pick the closest. Choose “other” to type your own.\" }),\n kindLabel: z.string().min(1, MESSAGES.kindLabel).max(40, \"keep the custom kind under 40 characters\").optional()\n .meta({ label: \"Custom kind\", placeholder: \"e.g. Fireside chat\", help: \"Only used when the kind is “other”.\" }),\n date: z.string().regex(DATE_RE, \"date must be written as YYYY-MM-DD, e.g. 2026-09-28\").refine(realDate, { message: MESSAGES.date })\n .meta({ label: \"Date\", input: \"date\", help: \"The day it happens. For a podcast or article, the day it comes out.\" }),\n startTime: time(\"Start time\", \"Leave blank for an all-day item or something without a set time.\"),\n endTime: time(\"End time\", \"Optional. Needs a start time.\"),\n timezone: z.enum(ZONES).optional()\n .meta({ label: \"Time zone\", help: \"Leave blank for the site's usual zone.\" }),\n location: z.string().min(1, \"location must not be empty when present\").optional()\n .meta({ label: \"Where\", placeholder: \"e.g. The SoundPlex, Pennsauken, NJ — or Online\", help: \"A place name and town, or “Online”. Shown under the title.\" }),\n url: z.string().url(\"the link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Link for details\", placeholder: \"https://…\", help: \"The event's own page, if it has one.\" }),\n heroImage: z.string().min(1, \"heroImage must be a path when present\").optional()\n .meta({ label: \"Picture\", help: \"Optional. Choose a picture and we size it for the web.\" }),\n heroImageAlt: z.string().min(1, MESSAGES.heroImageAlt).optional()\n .meta({ label: \"Picture description\", placeholder: \"What the picture shows\", help: \"A sentence describing the picture, for screen readers and Google Images.\" }),\n ogImage: z.string().min(1, \"ogImage must be a path when present\").optional()\n .meta({ label: \"Social share image\", help: \"Shown when someone shares the link. Leave blank to reuse the picture.\" }),\n cancelled: z.boolean().optional()\n .meta({ label: \"Cancelled\", help: \"Keeps the event on the page, marked cancelled.\" }),\n cancelledNote: z.string().max(300, \"keep the note under 300 characters\").optional()\n .meta({ label: \"Cancellation note\", placeholder: \"e.g. Postponed — new date coming soon\", help: \"A short line shown with the cancelled event.\" }),\n rescheduledTo: z.string().regex(SLUG_RE, \"rescheduledTo must be the web address (slug) of the replacement event\").optional()\n .meta({ label: \"Moved to\", placeholder: \"the slug of the new event\", help: \"If this moved to a new date, the web address of the replacement.\" }),\n previousDate: z.string().regex(DATE_RE, \"previousDate must be YYYY-MM-DD\").optional()\n .meta({ label: \"Previous date\", help: \"If this event moved, the date it was originally on.\" }),\n };\n}\n\ntype Core<K extends string> = {\n title: string; slug: string; summary: string;\n kind?: K | typeof OTHER_KIND; kindLabel?: string;\n date: string; startTime?: string; endTime?: string; timezone?: Zone;\n location?: string; url?: string;\n heroImage?: string; heroImageAlt?: string; ogImage?: string;\n cancelled?: boolean; cancelledNote?: string; rescheduledTo?: string; previousDate?: string;\n};\ntype Venues = { venue: string };\ntype Tickets = { rsvpUrl?: string; capacity?: number; closed?: boolean; private?: boolean };\ntype Appearances = { host?: string; recordingUrl?: string; slidesUrl?: string };\n\nexport type EventFrontmatter<G extends EventGroup = never, K extends string = DefaultKind> =\n Core<K>\n & (\"venues\" extends G ? Venues : object)\n & (\"tickets\" extends G ? Tickets : object)\n & (\"appearances\" extends G ? Appearances : object);\n\nexport function eventSchema<G extends EventGroup = never, K extends string = DefaultKind>(\n options: EventSchemaOptions<G, K> = {},\n): z.ZodType<EventFrontmatter<G, K>> {\n const kinds = (options.kinds ?? DEFAULT_KINDS) as unknown as readonly [K, ...K[]];\n const groups = (options.with ?? []).filter((g) => (EVENT_GROUPS as readonly string[]).includes(g));\n const shape = { ...coreShape(kinds), ...Object.assign({}, ...groups.map((g) => GROUP_SHAPES[g])) };\n\n const schema = z.object(shape).strict()\n .refine((d) => !d.endTime || !!d.startTime, { message: MESSAGES.endTime, path: [\"endTime\"] })\n .refine((d) => !d.heroImage || !!d.heroImageAlt, { message: MESSAGES.heroImageAlt, path: [\"heroImageAlt\"] })\n .refine((d) => d.kind !== OTHER_KIND || !!d.kindLabel, { message: MESSAGES.kindLabel, path: [\"kindLabel\"] })\n .refine((d) => d.kind === OTHER_KIND || !d.kindLabel, { message: \"a custom kind is only used when the kind is “other”\", path: [\"kindLabel\"] });\n return schema as unknown as z.ZodType<EventFrontmatter<G, K>>;\n}\n\n/** The chip text: the custom label for \"other\", else the kind in Title Case, else null. */\nexport function kindOf(fm: { kind?: string; kindLabel?: string }): string | null {\n if (fm.kind === OTHER_KIND) return fm.kindLabel?.trim() || null;\n if (!fm.kind) return null;\n return fm.kind.replace(/[-_]+/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\n/** 5degrees-style file names: 2026-09-28-ai-talk.mdx. */\nexport function eventFilename(fm: Record<string, unknown>): string {\n return `${String(fm.date)}-${String(fm.slug)}.mdx`;\n}\n\n/** slugFromFilename for eventFilename: \"2026-09-28-ai-talk.mdx\" → \"ai-talk\". */\nexport function slugFromEventFilename(fileName: string): string | null {\n const m = /^\\d{4}-\\d{2}-\\d{2}-([a-z0-9]+(?:-[a-z0-9]+)*)\\.mdx$/.exec(fileName);\n return m ? m[1] : null;\n}\n\n/** Blog-style file names: ai-talk.mdx. */\nexport function slugFilename(fm: Record<string, unknown>): string {\n return `${String(fm.slug)}.mdx`;\n}\n","/**\n * Turn \"a date, a wall-clock time, a zone\" into instants, and back into words.\n * No date library: zone offsets come from Intl.DateTimeFormat, which every\n * runtime we target ships with full tz data.\n */\n\nimport { isZone, zoneToIana } from \"./zones\";\n\nexport interface WhenInput {\n date: string;\n startTime?: string;\n endTime?: string;\n timezone?: string;\n}\n\nexport interface When {\n start: Date;\n end: Date | null;\n /** IANA zone the event is in. */\n zone: string;\n allDay: boolean;\n}\n\nexport interface WhenOptions {\n /** IANA zone used when the event has none, e.g. \"America/New_York\". */\n defaultZone: string;\n}\n\nexport function zoneFor(fm: { timezone?: string }, opts: WhenOptions): string {\n return isZone(fm.timezone) ? zoneToIana(fm.timezone) : opts.defaultZone;\n}\n\n/** Offset (ms) of `zone` from UTC at the given instant. */\nfunction offsetAt(instant: Date, zone: string): number {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: zone, hourCycle: \"h23\",\n year: \"numeric\", month: \"2-digit\", day: \"2-digit\", hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\",\n }).formatToParts(instant);\n const n = (t: string) => Number(parts.find((p) => p.type === t)?.value ?? 0);\n const asUtc = Date.UTC(n(\"year\"), n(\"month\") - 1, n(\"day\"), n(\"hour\"), n(\"minute\"), n(\"second\"));\n return asUtc - instant.getTime();\n}\n\n/** The instant at which the wall clock in `zone` reads y-m-d h:mm. */\nexport function zonedInstant(date: string, hhmm: string, zone: string): Date {\n const [y, m, d] = date.split(\"-\").map(Number);\n const [h, min] = hhmm.split(\":\").map(Number);\n const wall = Date.UTC(y, m - 1, d, h, min);\n // Guess with the offset at the wall time read as UTC, then correct once — the\n // second pass lands exactly except inside a DST gap, where it picks the later side.\n let guess = wall - offsetAt(new Date(wall), zone);\n guess = wall - offsetAt(new Date(guess), zone);\n return new Date(guess);\n}\n\nexport function eventWhen(fm: WhenInput, opts: WhenOptions): When {\n const zone = zoneFor(fm, opts);\n if (!fm.startTime) {\n return { start: zonedInstant(fm.date, \"00:00\", zone), end: null, zone, allDay: true };\n }\n const start = zonedInstant(fm.date, fm.startTime, zone);\n const end = fm.endTime ? zonedInstant(fm.date, fm.endTime, zone) : null;\n return { start, end, zone, allDay: false };\n}\n\n/** Midnight at the start of the day AFTER the event, in its zone — when an all-day item is over. */\nexport function endOfDay(when: When): Date {\n const next = new Date(when.start.getTime() + 36 * 3_600_000); // safely into the next day\n const ymd = new Intl.DateTimeFormat(\"en-CA\", { timeZone: when.zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(next);\n return zonedInstant(ymd, \"00:00\", when.zone);\n}\n\n/** The moment the event is over: its end, else its start, else the end of its day. */\nexport function endsAt(when: When): Date {\n if (when.allDay) return endOfDay(when);\n return when.end ?? when.start;\n}\n\nexport function formatWhen(when: When, opts: { locale?: string } = {}): string {\n const locale = opts.locale ?? \"en-US\";\n const day = new Intl.DateTimeFormat(locale, { timeZone: when.zone, weekday: \"short\", month: \"short\", day: \"numeric\", year: \"numeric\" }).format(when.start);\n if (when.allDay) return day;\n\n const clock = (d: Date) =>\n new Intl.DateTimeFormat(locale, { timeZone: when.zone, hour: \"numeric\", minute: \"2-digit\", hour12: true }).format(d).toLowerCase();\n const zoneName = new Intl.DateTimeFormat(locale, { timeZone: when.zone, timeZoneName: \"short\" })\n .formatToParts(when.start).find((p) => p.type === \"timeZoneName\")?.value ?? \"\";\n\n if (!when.end) return `${day} · ${clock(when.start)} ${zoneName}`.trim();\n\n // \"7:00–9:00 pm\" when both share a meridiem; \"11:00 am–1:00 pm\" otherwise.\n const s = clock(when.start);\n const e = clock(when.end);\n const [sTime, sMer] = s.split(\" \");\n const [, eMer] = e.split(\" \");\n const range = sMer === eMer ? `${sTime}–${e}` : `${s}–${e}`;\n return `${day} · ${range} ${zoneName}`.trim();\n}\n\n/** The calendar day (YYYY-MM-DD) of an instant in a zone. */\nexport function dayIn(instant: Date, zone: string): string {\n return new Intl.DateTimeFormat(\"en-CA\", { timeZone: zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(instant);\n}\n","/**\n * Where an event sits relative to now, and how a list should order them.\n * Pure: everything takes `now` so tests and static builds are deterministic.\n */\n\nimport { dayIn, endsAt, eventWhen, type WhenInput, type WhenOptions } from \"./when\";\n\nexport type EventStatus = \"cancelled\" | \"rescheduled\" | \"past\" | \"today\" | \"upcoming\";\n\nexport interface StatusInput extends WhenInput {\n cancelled?: boolean;\n rescheduledTo?: string;\n}\n\nexport function eventStatus(fm: StatusInput, now: Date, opts: WhenOptions): EventStatus {\n if (fm.cancelled) return \"cancelled\";\n if (fm.rescheduledTo) return \"rescheduled\";\n const when = eventWhen(fm, opts);\n if (endsAt(when).getTime() < now.getTime()) return \"past\";\n if (dayIn(when.start, when.zone) === dayIn(now, when.zone)) return \"today\";\n return \"upcoming\";\n}\n\nexport interface SplitResult<T> {\n /** Soonest first. */\n upcoming: T[];\n /** Most recent first. */\n past: T[];\n}\n\n/**\n * Upcoming = not yet over (today's items included). Cancelled and rescheduled\n * items stay wherever their date puts them — the page marks them, it does not hide them.\n */\nexport function splitEvents<T extends StatusInput>(items: readonly T[], now: Date, opts: WhenOptions): SplitResult<T> {\n const stamped = items.map((fm) => ({ fm, when: eventWhen(fm, opts) }));\n const over = (x: (typeof stamped)[number]) => endsAt(x.when).getTime() < now.getTime();\n const upcoming = stamped.filter((x) => !over(x)).sort((a, b) => a.when.start.getTime() - b.when.start.getTime());\n const past = stamped.filter(over).sort((a, b) => b.when.start.getTime() - a.when.start.getTime());\n return { upcoming: upcoming.map((x) => x.fm), past: past.map((x) => x.fm) };\n}\n","/**\n * What a site spreads into defineContentType so an events type is ten lines:\n * field order, the grouped sections, the image fields.\n */\n\nimport type { EventGroup } from \"./groups\";\n\nexport interface EventRegistryDefaults {\n order: string[];\n groups: { label: string; fields: string[] }[];\n images: string[];\n inputs: Record<string, never>;\n}\n\nexport function eventRegistryDefaults(options: { with?: readonly EventGroup[] } = {}): EventRegistryDefaults {\n const on = new Set(options.with ?? []);\n const where = on.has(\"venues\") ? \"venue\" : \"location\";\n\n const order = [\"title\", \"slug\", \"summary\", \"kind\", \"kindLabel\", \"date\", \"startTime\", \"endTime\", \"timezone\", where, \"url\"];\n if (on.has(\"venues\")) order.push(\"location\"); // extra directions under the venue\n\n const groups: EventRegistryDefaults[\"groups\"] = [];\n if (on.has(\"tickets\")) groups.push({ label: \"Tickets & RSVP\", fields: [\"rsvpUrl\", \"capacity\", \"closed\", \"private\"] });\n if (on.has(\"appearances\")) groups.push({ label: \"Appearance details\", fields: [\"host\", \"recordingUrl\", \"slidesUrl\"] });\n groups.push({ label: \"Pictures\", fields: [\"heroImage\", \"heroImageAlt\", \"ogImage\"] });\n groups.push({ label: \"Changes\", fields: [\"cancelled\", \"cancelledNote\", \"rescheduledTo\", \"previousDate\"] });\n\n // Inputs come from .meta() in the schema; the key is here so a site can spread and then override.\n return { order, groups, images: [\"heroImage\", \"ogImage\"], inputs: {} };\n}\n"]}