Commit 60104b4
feat(website): redesign homepage feature grid with native-surface artifacts (#479)
* feat(website): balance wide feature tiles with a right-hand media column
The bento wide tiles (the hero and the void-fill stretches) carried
their text in a left column and left the right side empty. Give every
card a `.feature-media` column that CSS reveals only on the wide tiles:
- By default it shows an oversized, faded copy of the feature's icon —
zero new assets, scales to every feature.
- A feature page that sets `image:` (a path under static/, e.g.
`img/features/auto-fix.png`) shows that screenshot instead, framed as
a dark terminal window matching the existing `.hero-demo` chrome, so
dark-mode terminal captures sit naturally on the light cards.
- The reveal is gated above the 880px breakpoint, so phones keep the
single-column, text-only stack.
The card text is wrapped in `.feature-card-body` so body and media can
sit side by side on the wide tiles. No `.mdsmith.yml` change: nothing
sets `image:` yet, so every tile renders the faded icon. Adding a real
screenshot later needs an optional `image?` leaf on the `feature` kind
plus the PNG under website/static/img/features/.
Verified against the real compiled CSS on the count-3 and count-4
pillars, desktop and mobile, with both the faded icon and a framed
screenshot.
* feat(website): gradient icon-box on wide tiles; generalize void-fill to data-tail
Addresses the Copilot review on #479:
- Void-fill now keys on a derived `data-tail = (count-2) mod 3`
(stamped for N>=4) instead of enumerated counts (1,3,4,6,7,9), so the
last row fills cleanly at ANY group size — verified for counts
5,6,7,10,13. N=1 and N=3 stay special-cased via data-count.
- The default media box is a soft forge-gradient panel carrying the
feature's OWN icon, centered and fully visible — not a faint glyph
bleeding off the edge.
- A screenshot (when `image:` is set) renders in full (height auto, no
crop) in a dark terminal frame that hugs the image.
- Empty the static .gitkeep so Hugo no longer publishes contributor
instructions at /img/features/.gitkeep; the how-to lives in the
feature-grid.html template comment.
Verified against the real compiled CSS and local lucide icons on all
five real pillars (counts 3,4,4,3,4) plus a 5-13 generalization grid,
desktop and mobile.
* style(website): ease the wide-tile wash into a right-to-left fade
The icon box read as a hard panel. Replace it with a forge wash that is
strongest at the tile's right edge and eases out to the left toward the
text — a multi-stop gradient approximating an ease curve (smooth, not a
straight ramp), bled to the tile's top/right/bottom edges so the colour
starts at the edge. Screenshot tiles keep their dark terminal frame.
* fix(website): reserve screenshot aspect-ratio and unify hero accent on mobile
Two review fixes on #479:
- .feature-shot reserves a 16:10 box (aspect-ratio) with
object-fit: contain, so a lazy-loaded screenshot no longer shifts the
layout (CLS) and is never cropped — 16:10 captures fill it exactly,
off-ratio ones letterbox on the dark frame.
- At <=880px the stacked hero drops its desktop bottom accent and takes
the same left accent as the other cards, so hover/focus is uniform.
* style(website): light the wide-tile icon with a layered forge glow
Replace the flat right->left wash with two layers for depth: a soft
radial glow-orb behind the icon for luminosity, over a smoother eased
right->left wash into the text. Keeps the single forge accent (brand
discipline) while adding the dimensional, lit quality mise gets right.
Screenshot tiles unchanged.
* feat(website): redesign feature grid with native-surface artifacts
Replace the bento feature tiles (faded-icon / gradient media panel) with
a refined typographic "pillar" layout — numbered pillar headers with a
hairline rule, white cards on canvas, and "Forged whole." with a
serif-italic accent. Each pillar's LEAD card now shows the feature in the
device frame it actually runs in, which proves "one engine, every surface":
- Clean, consistent Markdown -> a terminal (check -> fix -> all passing)
- One engine, every surface -> a VS Code editor (squiggle + Quick Fix)
- A connected docs tree -> a dependency graph (broken anchor flagged)
- Markdown as a single source -> a rendered file with a catalog regen diff
- Built for your pipeline -> a CI checks panel with the release gate
The grid stays data-driven from docs/features/*.md front matter; a
group->artifact map keys each lead to a partial under
layouts/partials/feature-artifacts/, with a graceful fallback (plain lead
card) for any unmapped group. Diagnostic codes in the artifacts use the
real rules: MDS001 (line length), MDS012 (bare URL), MDS006 (trailing
spaces), MDS027 (cross-file anchor), MDS019 (catalog). The artifacts are
website-only visuals; the README <?include?> is unaffected.
Removes the old .feature-* CSS/markup wholesale (the new layout shares no
classes with it). Verified by rendering the production app.css against the
approved mockup at desktop and mobile, and by mdsmith check (413, 0
failures). Real pillar counts (3-4 cards) match the rendered layout.
* chore(website): remove orphaned feature-screenshot placeholder
The grid redesign replaced the per-feature image: screenshot slot with
authored artifact partials, so website/static/img/features/.gitkeep is no
longer referenced by any template or stylesheet. Removing it also drops
the non-empty placeholder a reviewer flagged (Hugo publishes static/
verbatim, so it would expose internal contributor notes).
* fix(website): address review — grid responsive query, hover, a11y
- The count=4 grid used @media(min-width:881px) to force 2 columns,
which overrode the base 3-column layout on every desktop and left it
dead (3 support cards rendered as an awkward 2+1). Flip to
@media(max-width:960px): desktops keep the clean 3-column row, tablets
collapse to 2, and <=880px collapses to 1 as before.
- .card is an <a>, so the global a:hover underline leaked onto cards;
add text-decoration:none and color:inherit to .card:hover.
- Restore aria-hidden on the decorative lucide icons (the .card-icon
wrapper and the "Learn more" arrow) that the rewrite dropped.
* fix(website): address review — heading outline and lead-card selectors
- Restore the heading hierarchy: the pillar label is an <h3> again
(H2 section -> H3 pillar -> H4 card) instead of a <span>; .pillar-name
gets margin: 0 so the flex header stays tight.
- Key the full-width lead span to .card--lead instead of positional
.card:first-child (base count=3/4, the tablet query, and the mobile
collapse), so an unmapped/fallback group's first card stays a normal
grid card instead of spanning like a lead.
* fix(website): address review — terminal title contrast, drop dead theme class
- Override the terminal artifact's title colour to --term-fg-dim; the
default steel-500 sat at ~3.5:1 on the near-black #070A0D bar.
- Drop the unused card--lead-{dark,light} theme plumbing (no CSS was
keyed off it; the artifact partials carry their own dark/light look).
The artifact map is now simply group -> partial path.
- Clarify the comment: an unmapped group renders its first card as a
normal (non-lead) grid card, not a lead.
* docs(website): refresh stale comments in the feature grid
- Header comment: the lead card is conditional on a mapped artifact (not
every group) and carries only `card--lead` (the theme class was
dropped); an unmapped group's first card is a plain .card.
- app.css: .rule-chip no longer relates to the removed .feature-card.
* fix(website): make the feature grid robust for any card count
Reviewer flagged that the grid only handled data-count 3/4: a pillar
with any other count (the grid is data-driven) would fall back to an
implicit single column with the lead card not spanning. Generalize:
- .card-grid gets a default grid-template-columns:
repeat(auto-fill, minmax(240px, 1fr)); the 3/4 column counts remain as
tuned overrides.
- .card--lead spans grid-column: 1 / -1 as a base rule (any count),
replacing the per-count span rules and the redundant tablet repeat.
- The mobile breakpoint collapses .card-grid generically (not just 3/4)
and resets the lead's grid-column.
Verified: the real 3/4 pillars render unchanged; a synthetic count-5
pillar lays out as a full-width lead + a clean support row (no
single-column collapse); mdsmith check green.
* fix(website): collapse 3/4-card pillars to one column on mobile
The previous commit genericized the mobile rule to `.card-grid { 1fr }`,
but the base `.card-grid[data-count="3"/"4"]` rules carry higher
specificity and sit outside any media query, so they kept 3/4-card
pillars multi-column at <=880px. List the data-count variants in the
mobile override so they collapse. Verified at 414px: the real 3/4
pillars and synthetic 2/5-card pillars all stack to a single column.
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 617df38 commit 60104b4
8 files changed
Lines changed: 1181 additions & 134 deletions
File tree
- website
- layouts
- partials
- feature-artifacts
- static/css
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
0 commit comments