Merge branch 'refactor/task-08-route-cards'
This commit is contained in:
@@ -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;
|
||||
---
|
||||
|
||||
<section class="group" aria-label={label}>
|
||||
<div class="grid" style={`--columns: ${columns}`}>
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--columns), 1fr);
|
||||
gap: 1px; /* hairline separators, drawn by the parent background */
|
||||
background: var(--line);
|
||||
}
|
||||
|
||||
/* Children paint their own background, which is what makes the 1px show. */
|
||||
.grid > :global(*) {
|
||||
background: var(--paper);
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
// RouteCard — one chapter card in the landing page's six-up route grid.
|
||||
//
|
||||
// Markup mirrors `index.html`'s `<article class="card">` block:
|
||||
// <b>{number}</b><h2>{title}</h2><p>{summary}</p><a href={href}>…</a>
|
||||
// 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;
|
||||
---
|
||||
|
||||
<article class="card">
|
||||
<b>{number}</b>
|
||||
<h2>{title}</h2>
|
||||
<p>{summary}</p>
|
||||
<a href={href}>{cta}</a>
|
||||
</article>
|
||||
|
||||
<style>
|
||||
/* Mirror chapters.css `.card` + landing.css `.route-grid .card` exactly. */
|
||||
.card {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex-direction: column;
|
||||
min-height: 220px;
|
||||
padding: 28px;
|
||||
background: var(--paper);
|
||||
}
|
||||
|
||||
.card b {
|
||||
color: var(--red);
|
||||
/* token-gap: legacy 24px fixed from chapters.css .card b; no --step-* covers 24px; owner design-system-keeper */
|
||||
font-size: 24px;
|
||||
font-family: ui-monospace, monospace;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
margin: 18px 0 8px;
|
||||
/* token-gap: legacy 25px fixed from chapters.css .card h2; --step-5 is clamp(24px,3vw,38px) and grows at wide viewports; owner design-system-keeper */
|
||||
font-size: 25px;
|
||||
letter-spacing: -0.04em;
|
||||
}
|
||||
|
||||
.card p {
|
||||
margin: 0 0 14px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.card a {
|
||||
/* Push the link to the bottom — carried from landing.css
|
||||
`.route-grid .card a { margin-top: auto }`. */
|
||||
margin-top: auto;
|
||||
color: var(--blue);
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.card a:focus-visible {
|
||||
outline: 3px solid var(--red);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.card {
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user