From c00964132ce84a84bcf05dae429deac657829938 Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 07:47:29 +0000 Subject: [PATCH] feat(blocks): add GridGroup and RouteCard for landing route grid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task 08 of the Astro refactor. The landing page's six chapter cards become two reusable components: - GridGroup: gap:1px hairline-separated wrapper that preserves the site's deliberate border-faking technique over a coloured parent background. - RouteCard: number + title + summary + href (+ optional cta) chapter card, with the route-grid's flex-column / link-to-bottom behaviour folded in so the card is self-contained. Both ship zero JS, use tokens only, and mirror the chapters.css / landing.css values exactly. Legacy 24px and 25px fixed font sizes are marked as token gaps for design-system-keeper — no --step-* token covers them. Schema gap: src/content/config.ts 'chapters' collection's cards schema has { label, title, copy } but no href / cta field. Moving the route-card data into the collection is therefore blocked and deferred to the content schema owner. Components are ready for task 12 to consume via props. Verified: pnpm run gate passed (15s, 42/42 assertions, no token findings). --- src/components/blocks/GridGroup.astro | 48 ++++++++++++++ src/components/blocks/RouteCard.astro | 92 +++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 src/components/blocks/GridGroup.astro create mode 100644 src/components/blocks/RouteCard.astro diff --git a/src/components/blocks/GridGroup.astro b/src/components/blocks/GridGroup.astro new file mode 100644 index 0000000..941289f --- /dev/null +++ b/src/components/blocks/GridGroup.astro @@ -0,0 +1,48 @@ +--- +// GridGroup — gap:1px hairline-separated card grid wrapper. +// +// The separator technique is deliberate house style: a `gap: 1px` over a +// coloured parent background fakes borders without `border` shorthand. Each +// direct child paints its own background, which is what makes the 1px seam +// show. Do not "fix" this into `border`. +// +// Built from `.agents/templates/components/grid-group.astro` per task 08 of +// the Astro refactor. The landing page wraps six `RouteCard` instances in +// this group; the route-grid layout also pushes each card's link to the +// bottom, which `RouteCard` carries itself so this wrapper stays generic. + +interface Props { + /** Accessible label for the group, surfaced as `aria-label` on the section. */ + label: string; + /** Number of columns at the widest breakpoint. */ + columns?: number; +} + +const { label, columns = 3 } = Astro.props; +--- + +
+
+ +
+
+ + diff --git a/src/components/blocks/RouteCard.astro b/src/components/blocks/RouteCard.astro new file mode 100644 index 0000000..f076921 --- /dev/null +++ b/src/components/blocks/RouteCard.astro @@ -0,0 +1,92 @@ +--- +// RouteCard — one chapter card in the landing page's six-up route grid. +// +// Markup mirrors `index.html`'s `
` block: +// {number}

{title}

{summary}

+// The `route-grid` wrapper in landing.css used to push each card's link to the +// bottom with `display:flex; flex-direction:column; margin-top:auto` on the +// anchor. That responsibility lives on the card itself now, so the card is +// self-contained — drop it into any gap:1px group and it lays out the same way. +// +// Built from `.agents/templates/components/static-block.astro` per task 08 of +// the Astro refactor. Steps on: +// - number — the "01" … "06" prefix +// - title — the chapter name (h2) +// - summary — the lede line under the title +// - href — link target for the chapter +// - cta — link text (the index page varies this: "Open chapter →", +// "Open lab →", "Open desk →"). Defaults to "Open chapter →". + +interface Props { + /** Two-digit prefix rendered in the chapter surface red, e.g. "01". */ + number: string; + /** Chapter name shown as the card's h2. */ + title: string; + /** One-line summary under the title. */ + summary: string; + /** Link target for the chapter. */ + href: string; + /** Link text. Varies per destination in the current landing page. */ + cta?: string; +} + +const { number, title, summary, href, cta = 'Open chapter →' } = Astro.props; +--- + +
+ {number} +

{title}

+

{summary}

+ {cta} +
+ +