+ const cardClassName = `${backgroundColor} ${cardPadding} ${cardGap} ${borderRadiusClass} shadow-[0px_0px_48px_0px_rgba(0,0,0,0.1)] ${interactiveCard ? "hover:shadow-[0px_0px_64px_0px_rgba(0,0,0,0.15)] transition-shadow duration-200" : ""} flex flex-col items-start justify-center relative ${cardWidth || "w-full"} ${href ? "no-underline text-inherit" : ""} ${className || ""}`;
+ const isLinkCard = Boolean(href) && interactiveCard;
+
+ const cardBody = (
+ <>
{/* Figma: Header = `border-b` row, `gap-px`, icon `pl-1 pr-2 py-2` + `border-l` on title. */}
+ {cardBody}
);
}
diff --git a/app/components/sections/GovernanceTemplateGrid/GovernanceTemplateGrid.tsx b/app/components/sections/GovernanceTemplateGrid/GovernanceTemplateGrid.tsx
index 69dd25b..f45e9b0 100644
--- a/app/components/sections/GovernanceTemplateGrid/GovernanceTemplateGrid.tsx
+++ b/app/components/sections/GovernanceTemplateGrid/GovernanceTemplateGrid.tsx
@@ -9,7 +9,13 @@ import type { GovernanceTemplateCatalogEntry } from "../../../../lib/templates/g
export interface GovernanceTemplateGridProps {
entries: GovernanceTemplateCatalogEntry[];
- onTemplateClick: (_slug: string) => void;
+ /**
+ * Real navigation target per card. Cards render as anchors so they are
+ * keyboard-focusable and work in a new tab.
+ */
+ hrefForTemplate: (_slug: string) => string;
+ /** Optional side effects on activate (analytics, draft reset). */
+ onTemplateClick?: (_slug: string) => void;
/**
* When true, use project **`md`** (640px) for a 2-column grid (e.g. `/use-cases`).
* Default keeps the template shell break at **768px**.
@@ -19,6 +25,7 @@ export interface GovernanceTemplateGridProps {
export function GovernanceTemplateGrid({
entries,
+ hrefForTemplate,
onTemplateClick,
twoColumnsFromMd = false,
}: GovernanceTemplateGridProps) {
@@ -105,9 +112,14 @@ export function GovernanceTemplateGrid({
/>
}
backgroundColor={card.backgroundColor}
- onClick={() => {
- onTemplateClick(card.slug);
- }}
+ href={hrefForTemplate(card.slug)}
+ onClick={
+ onTemplateClick
+ ? () => {
+ onTemplateClick(card.slug);
+ }
+ : undefined
+ }
/>
))}
diff --git a/app/components/sections/RuleStack/RuleStack.container.tsx b/app/components/sections/RuleStack/RuleStack.container.tsx
index e079f95..fc4b3ed 100644
--- a/app/components/sections/RuleStack/RuleStack.container.tsx
+++ b/app/components/sections/RuleStack/RuleStack.container.tsx
@@ -5,10 +5,10 @@
*/
import { memo, useEffect, useState } from "react";
-import { useRouter } from "next/navigation";
import { useTranslation } from "../../../contexts/MessagesContext";
import { logger } from "../../../../lib/logger";
import { prepareFreshCreateFlowEntrySync } from "../../../(app)/create/utils/prepareFreshCreateFlowEntry";
+import { buildTemplateReviewHref } from "../../../(app)/create/utils/flowSteps";
import {
fetchTemplates,
isTemplatesFetchAborted,
@@ -34,7 +34,6 @@ declare global {
const RuleStackContainer = memo