From 349cd252f733b01dc06c578c6a7ab466ca87b9ff Mon Sep 17 00:00:00 2001 From: Punch Date: Fri, 5 Jun 2026 17:48:13 +0000 Subject: [PATCH] Route Guide three-categories cards to canonical goal copy --- BACKLOG.md | 2 +- src/components/QuickstartGuide.tsx | 61 +++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/BACKLOG.md b/BACKLOG.md index 40836b9..8a9ffed 100644 --- a/BACKLOG.md +++ b/BACKLOG.md @@ -106,7 +106,7 @@ If any seat would be confused, the component fails. ### Guide (`/guide`) - TOC / sticky nav — ○ ○ ○ -- "The three categories" section — ○ ○ ○ +- "The three categories" section — ● ● ● — three round cards now use the canonical one-liner goal strings from `App.tsx:CATEGORY_META` (verified character-exact: "Lightest part that survives the load wins." / "Highest stiffness-per-gram wins." / "Least bending under the applied load wins.") so the Guide / category-page / spec-detail trio agree on vocabulary. Each card is now a routed `` with hover state + `Open category →` CTA — first-timer who reads "mass = lightest wins" can click straight to the 15 live problems instead of hunting through the TOC. Unit chips become cursor-help `↓ minimize g` / `↑ maximize N/(mm·g)` / `↓ minimize mm` (154/162/179-char tooltips defining each unit + describing how the FEA harness computes the score). Tier line "easy / medium / hard" wrapped in a 191-char cursor-help tooltip reusing the canonical wording from `App.tsx:711` (step 354) so the same difficulty explanation appears in Guide + Category-page filter row. Puppeteer-verified live at 1440×900 on `/guide#categories`: 3 routed cards · all 3 canonical goal strings present · old "Lightest part that passes FEA" copy gone · click on Mass card navigates to `/problems/round_001`. (`QuickstartGuide.tsx` L343–384 + L443–489) - "Step 1 — Set up" → "Step 5 — Submit" — ○ ○ ○ - "Whitelisted models" — ○ ○ ○ - "Agent architecture patterns" — ○ ○ ○ diff --git a/src/components/QuickstartGuide.tsx b/src/components/QuickstartGuide.tsx index 466c30d..6c907a8 100644 --- a/src/components/QuickstartGuide.tsx +++ b/src/components/QuickstartGuide.tsx @@ -1,4 +1,5 @@ import { useEffect, useRef, useState } from "react"; +import { Link } from "react-router-dom"; import { API_BASE_URL } from "../lib/api"; const FORGE_REPO = "https://github.com/PunchTheDev/forge"; @@ -339,39 +340,48 @@ function Section({ id, title, children }: { id?: string; title: string; children ); } +// `goal` strings are the canonical one-liners from App.tsx:CATEGORY_META — same vocab the +// category-page H1 + spec-detail CATEGORY_PILL.goal row use, so the first-timer's mental +// model carries across pages. `subdesc` adds the engineering rationale below. const CATEGORIES = [ { id: "round_001", label: "Mass Optimization", - metric: "mass_grams", unit: "g", + unitTip: + "g = grams. Lower is better. Score is the mass of the generated part in grams — measured by the FEA harness from the STEP file's volume × material density.", direction: "minimize" as const, color: "text-forge-green", bg: "bg-forge-green/10", border: "border-forge-green/30", - desc: "Lightest part that passes FEA. Material density and topology matter most.", + goal: "Lightest part that survives the load wins.", + subdesc: "Material density and topology matter most — every gram pruned that still passes FEA improves your score.", }, { id: "round_002", label: "Stiffness/Weight", - metric: "stiffness_to_weight", unit: "N/(mm·g)", + unitTip: + "N/(mm·g) = newtons per millimetre of deflection, per gram of part. Higher is better. Score = applied load ÷ tip deflection ÷ mass — a structural-efficiency ratio.", direction: "maximize" as const, color: "text-forge-accent", bg: "bg-forge-accent/10", border: "border-forge-accent/30", - desc: "Stiffness per gram — maximize load resistance while minimizing mass.", + goal: "Highest stiffness-per-gram wins.", + subdesc: "Maximize load resistance while minimizing mass — geometry-driven, not just heavier-is-better.", }, { id: "round_003", label: "Deflection", - metric: "deflection_mm", unit: "mm", + unitTip: + "mm = millimetres of tip deflection under the applied load. Lower is better. Score is the displacement of the load point measured by CalculiX after applying the spec's load vector.", direction: "minimize" as const, color: "text-forge-red", bg: "bg-forge-red/10", border: "border-forge-red/30", - desc: "Least tip deflection under load. Rigidity over lightness — thick cross-sections win.", + goal: "Least bending under the applied load wins.", + subdesc: "Rigidity over lightness — thick cross-sections and well-placed ribs win.", }, ]; @@ -442,24 +452,47 @@ export function QuickstartGuide() {

Every PR is evaluated on one problem from each category. Your composite score is what - determines your ranking — not just your best single-problem result. + determines your ranking — not just your best single-problem result. Click any card + below to jump to the live category page and start with a real problem.

{CATEGORIES.map((cat) => ( -
+
{cat.label}
-
- {cat.direction === "minimize" ? "↓ minimize" : "↑ maximize"} {cat.unit} +
+ + {cat.direction === "minimize" ? "↓ minimize" : "↑ maximize"} {cat.unit} +
-
{cat.desc}
-
+
+ {cat.goal} +
+
{cat.subdesc}
+
+ Open category → +
+ ))}

- Each category has 15 problems at three difficulty - tiers (easy / medium / hard). PR CI runs 1 easy problem per category for a quick pass/fail check (~5 min). + Each category has 15 problems at{" "} + + three difficulty tiers (easy / medium / hard) + + . PR CI runs 1 easy problem per category for a quick pass/fail check (~5 min). Full scoring runs across all 45 problems — no sampling variance in the final rank.