diff --git a/docs/index.md b/docs/index.md
index 7d53bb8c..2d848fc3 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -204,10 +204,10 @@ launchpad tile or SAP Build Work Zone.
## Made for AI agents
-An app is one ABAP class, so an agent writes the whole thing — UI and logic — in one go, and a
-working app or a new screen is a matter of minutes. The abap2UI5
-linter and the MCP server let the agent double check its own work before a developer
-looks at it.
+An app is one ABAP class, so an agent writes the whole thing — UI and logic —
+in one go, and a working app or a new screen is a matter of minutes. The
+abap2UI5 linter and the MCP server let the agent double-check its own work
+before a developer looks at it.
→ *More on [Developing with AI](/get_started/ai)*
diff --git a/scripts/build-site.mjs b/scripts/build-site.mjs
index 3cf2bb20..e96753ce 100644
--- a/scripts/build-site.mjs
+++ b/scripts/build-site.mjs
@@ -815,7 +815,7 @@ const bands = (body, tiles = '') => {
* rather than being given a band it did not ask for. */
const lead = parts[0].startsWith('
part.includes('a2ui5-play'));
- return lead + parts.map((part, i) => {
+ const rendered = parts.map((part, i) => {
const id = (part.match(/^ 0 && i < hinge ? ' data-card' : '';
/* ...and the hinge marks itself, for the same reason: what needs the full
@@ -823,7 +823,14 @@ const bands = (body, tiles = '') => {
const demo = i === hinge ? ' data-demo' : '';
return ``
+ (i === hinge ? tiles : '');
- }).join('');
+ });
+ /* The cards share one grid of their own, so every row of it is as tall as
+ the tallest card: four panels of one size, whatever each one says. In the
+ page's grid only the two cards on a row could be held to one height, and
+ the second row sat visibly taller than the first. */
+ const cards = hinge > 0 ? rendered.slice(0, hinge) : [];
+ const rest = hinge > 0 ? rendered.slice(hinge) : rendered;
+ return lead + (cards.length ? `
${cards.join('')}
` : '') + rest.join('');
};
const home = ({ body, fm, page }) => {
diff --git a/scripts/site-css/docs.css b/scripts/site-css/docs.css
index deed8152..3584e617 100644
--- a/scripts/site-css/docs.css
+++ b/scripts/site-css/docs.css
@@ -754,9 +754,11 @@ html { scroll-padding-top: 62px; }
* label/value pairs is homework, not an answer. What was load-bearing in it
* went into the answers themselves.
*
- * Two by two, every card the same width and, by `align-items: stretch`, the
- * same height as the one beside it. Three sections in a column beside a table
- * never balanced against anything; four balance against each other.
+ * Two by two, every card the same width and the same height - not only as
+ * the one beside it but as all four, because the build puts them in a grid
+ * of their own whose rows are `1fr`: every row as tall as the tallest card.
+ * Three sections in a column beside a table never balanced against anything;
+ * four balance against each other.
*
* Raised rather than ruled. A hairline over a heading separates bands read in
* order; these are read in any order, so each is a panel of its own - the
@@ -768,6 +770,13 @@ html { scroll-padding-top: 62px; }
* Edit-on-GitHub link dropped that card out of the grid without a word. A
* wording change is the one edit this page invites; it must not be able to
* break the layout. See bands( ) in build-site.mjs. */
+.home .cards {
+ grid-column: 1 / -1;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ grid-auto-rows: minmax(0, 1fr);
+ gap: 24px;
+}
.home .band[data-card] {
grid-column: auto;
padding: 22px 24px 24px;
@@ -805,7 +814,7 @@ html { scroll-padding-top: 62px; }
@media (max-width: 860px) {
/* One column again: two 300px columns of prose are worse than a long page. */
- .home .vp-doc.bands { display: block; }
+ .home .vp-doc.bands, .home .cards { display: block; }
/* `display: block` drops the row gap with the grid; the tile row carries
its own, like the cards. */
.home .bands .tiles { margin-top: 24px; }