Add the Workshops page and keep each sign-up on the site.

The form is built once to the settled field set, and a valid send is saved before anyone is emailed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
adilalloandCursor committed 2026-11-03 19:56:49 -07:00
1 parent 974a5ace4c
commit c0ba3a3798
50 files changed
+2773 -1

No files matched your search

@@ -71,6 +71,19 @@ const QuoteBlockContainer = memo<QuoteBlockProps>(
"text-[14px] leading-[120%] md:text-[20px] md:leading-[120%] md:tracking-[0.24px] lg:text-[28px] xl:text-[36px]",
showDecor: true,
},
citation: {
container:
"bg-black px-[var(--space-400)] py-[var(--space-1200)] md:px-[var(--space-1200)] lg:px-[var(--space-2400)] lg:py-[120px]",
card: "",
gap: "",
avatarGap: "",
avatar: "",
quote: "text-[28px] leading-[34px] md:text-[40px] md:leading-[48px]",
author: "text-[12px] leading-[16px] tracking-[0.08em]",
source: "text-[12px] leading-[16px] tracking-[0.08em]",
showDecor: false,
citationLayout: true,
},
statement: {
container:
"flex w-full flex-col items-center px-[var(--space-800)] py-[var(--space-1200)] md:px-[var(--space-2400)] md:py-[var(--space-1200)]",
@@ -2,7 +2,8 @@ export type QuoteBlockVariantValue =
| "compact"
| "standard"
| "extended"
| "statement";
| "statement"
| "citation";
export interface QuoteBlockProps {
/** Default `standard` (home portrait quote). **`statement`** = yellow Section / Quote (**About** + **`/use-cases`** — two paragraphs below **`lg`**, one paragraph from **`lg`**; [21967-24638](https://www.figma.com/design/agv0VBLiBlcnSAaiAORgPR/Community-Rule-System?node-id=21967-24638&m=dev)). */
@@ -45,6 +46,8 @@ export interface VariantConfig {
* When true, render Figma **Section/Quote** layout (yellow surface; stacked copy below **`lg`**, single paragraph from **`lg`**; no attribution).
*/
statementLayout?: boolean;
/** Lavender citation quote used on Workshops. No avatar. */
citationLayout?: boolean;
}
export interface QuoteBlockViewProps {
@@ -24,6 +24,49 @@ function QuoteBlockView({
const t = useTranslation("quoteBlock");
const avatarAlt = t("avatarAlt").replace("{author}", author);
if (config.citationLayout) {
return (
<section
data-figma-node="23983-53436"
className={`${config.container} ${className}`.trim()}
aria-labelledby={quoteId}
>
<figure className="relative mx-auto w-full max-w-[1216px] overflow-hidden rounded-[24px] bg-[var(--color-surface-invert-brand-lavender)] px-[var(--space-600)] py-[var(--space-1000)] md:px-[var(--space-1200)] md:py-[var(--space-1800)]">
<div
className="pointer-events-none absolute -right-10 -top-16 size-[280px] rounded-full bg-white/25"
aria-hidden
/>
<div
className="pointer-events-none absolute -bottom-20 right-16 size-[320px] rounded-full bg-white/20"
aria-hidden
/>
<blockquote id={quoteId} className="relative">
<p
className={`font-bricolage-grotesque font-medium text-[var(--color-content-invert-primary)] ${config.quote}`}
>
“{quote}”
</p>
</blockquote>
<figcaption className="relative mt-10 flex flex-col gap-1">
<cite
id={authorId}
className={`font-inter not-italic uppercase text-[var(--color-content-invert-primary)] ${config.author}`}
>
{author}
</cite>
{source ? (
<p
className={`font-inter uppercase text-[var(--color-content-invert-primary)] ${config.source}`}
>
{source}
</p>
) : null}
</figcaption>
</figure>
</section>
);
}
if (config.statementLayout) {
const statementTextClass =
"font-bricolage-grotesque text-medium-heading text-[var(--color-surface-default-tertiary)] md:text-xx-large-heading";