162 lines
5.7 KiB
TypeScript
162 lines
5.7 KiB
TypeScript
/**
|
|
* Governance template cards aligned with Figma Community-Rule-System node 21764-16435
|
|
* (Card / Rule variants: icon + title + short description + surface color).
|
|
*
|
|
* Each slug is seeded in Prisma and links to `/create/review-template/[slug]`.
|
|
*/
|
|
|
|
export type GovernanceTemplateCatalogEntry = {
|
|
slug: string;
|
|
title: string;
|
|
description: string;
|
|
/** Tailwind background class — colors from Figma invert/brand surfaces */
|
|
backgroundColor: string;
|
|
/** Path under public/ for getAssetPath() — Figma Asset / Template Mark */
|
|
iconPath: string;
|
|
};
|
|
|
|
/** SVGs in `public/assets/template-mark/<slug>.svg` (kebab-case slug). */
|
|
export function governanceTemplateIconPath(slug: string): string {
|
|
return `assets/template-mark/${slug}.svg`;
|
|
}
|
|
|
|
/**
|
|
* Order matches the Figma stack (top → bottom).
|
|
*/
|
|
export const GOVERNANCE_TEMPLATE_CATALOG: GovernanceTemplateCatalogEntry[] = [
|
|
{
|
|
slug: "consensus",
|
|
title: "Consensus",
|
|
description:
|
|
"Important decisions require unanimous agreement. Proposals pass only if no serious objections remain.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-positive-secondary)]",
|
|
iconPath: governanceTemplateIconPath("consensus"),
|
|
},
|
|
{
|
|
slug: "consensus-clusters",
|
|
title: "Circles",
|
|
description:
|
|
"Units called Circles have the ability to decide and act on matters in their domains, which their members agree on through a Council.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-brand-teal)]",
|
|
iconPath: governanceTemplateIconPath("consensus-clusters"),
|
|
},
|
|
{
|
|
slug: "solidarity-network",
|
|
title: "Solidarity Network",
|
|
description:
|
|
"Power is held by autonomous \"cells.\" A central hub acts as a switchboard for resources but cannot dictate cell activities.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-positive-primary)]",
|
|
iconPath: governanceTemplateIconPath("solidarity-network"),
|
|
},
|
|
{
|
|
slug: "sortition-jury",
|
|
title: "Sortition (Jury)",
|
|
description:
|
|
"A representative sample of the community is chosen by lottery to form a temporary council.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-brand-lavender)]",
|
|
iconPath: governanceTemplateIconPath("sortition-jury"),
|
|
},
|
|
{
|
|
slug: "liquid-democracy",
|
|
title: "Liquid Democracy",
|
|
description:
|
|
"Members can vote directly or delegate their vote to a trusted peer on a per-topic basis.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-brand-kiwi)]",
|
|
iconPath: governanceTemplateIconPath("liquid-democracy"),
|
|
},
|
|
{
|
|
slug: "do-ocracy",
|
|
title: "Do-ocracy",
|
|
description:
|
|
"Authority is granted to those doing the work. If you do the task, you decide how it gets done.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-brand-royal)]",
|
|
iconPath: governanceTemplateIconPath("do-ocracy"),
|
|
},
|
|
{
|
|
slug: "quadratic-governance",
|
|
title: "Quadratic Governance",
|
|
description:
|
|
"Voting cost is squared (V²), preventing a majority from steamrolling a passionate minority.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-brand-secondary)]",
|
|
iconPath: governanceTemplateIconPath("quadratic-governance"),
|
|
},
|
|
{
|
|
slug: "federated-clusters",
|
|
title: "Federated Clusters",
|
|
description:
|
|
"Independent groups share a central brand/charter but have total autonomy over internal rules.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-brand-primary)]",
|
|
iconPath: governanceTemplateIconPath("federated-clusters"),
|
|
},
|
|
{
|
|
slug: "devolution",
|
|
title: "Devolution",
|
|
description:
|
|
"Starts as a Dictatorship for speed, moving to a Board, and finally to full community ownership.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-negative-secondary)]",
|
|
iconPath: governanceTemplateIconPath("devolution"),
|
|
},
|
|
{
|
|
slug: "benevolent-dictator",
|
|
title: "Benevolent Dictator",
|
|
description:
|
|
"A single individual holds ultimate power, usually intended as a temporary state until the project is stable.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-negative-primary)]",
|
|
iconPath: governanceTemplateIconPath("benevolent-dictator"),
|
|
},
|
|
{
|
|
slug: "petition",
|
|
title: "Petition",
|
|
description:
|
|
"Any participant can propose a rule change. If enough sign it, it goes to a general vote.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-brand-teal)]",
|
|
iconPath: governanceTemplateIconPath("petition"),
|
|
},
|
|
{
|
|
slug: "self-appointed-board",
|
|
title: "Self-Appointed Board",
|
|
description:
|
|
"An existing board selects its own successors to preserve a specific mission over time.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-brand-rust)]",
|
|
iconPath: governanceTemplateIconPath("self-appointed-board"),
|
|
},
|
|
{
|
|
slug: "elected-board",
|
|
title: "Elected Board",
|
|
description:
|
|
"An elected board determines policies and organizes their implementation.",
|
|
backgroundColor: "bg-[var(--color-surface-invert-warning-secondary)]",
|
|
iconPath: governanceTemplateIconPath("elected-board"),
|
|
},
|
|
];
|
|
|
|
const bySlug = new Map(
|
|
GOVERNANCE_TEMPLATE_CATALOG.map((e) => [e.slug, e] as const),
|
|
);
|
|
|
|
/**
|
|
* Order for the home “Popular templates” row (four cards). Must match catalog slugs.
|
|
*/
|
|
export const GOVERNANCE_TEMPLATE_HOME_SLUGS: readonly string[] = [
|
|
"consensus-clusters",
|
|
"consensus",
|
|
"elected-board",
|
|
"petition",
|
|
];
|
|
|
|
export function getGovernanceTemplatesForHome(): GovernanceTemplateCatalogEntry[] {
|
|
return GOVERNANCE_TEMPLATE_HOME_SLUGS.map((slug) => {
|
|
const e = bySlug.get(slug);
|
|
if (!e) {
|
|
throw new Error(`governanceTemplateCatalog: missing slug "${slug}"`);
|
|
}
|
|
return e;
|
|
});
|
|
}
|
|
|
|
export function getGovernanceTemplateCatalogEntry(
|
|
slug: string,
|
|
): GovernanceTemplateCatalogEntry | undefined {
|
|
return bySlug.get(slug);
|
|
}
|