Hub pages 2/4: {card-group}, {link-card}, and {explore} - #3826
Merged
Conversation
florent-leborgne
force-pushed
the
feature/hub-card-explore
branch
2 times, most recently
from
August 11, 2026 08:46
72fb5a2 to
b5e2d23
Compare
florent-leborgne
force-pushed
the
feature/hub-card-explore
branch
2 times, most recently
from
August 11, 2026 15:15
47c33d0 to
a8a4319
Compare
florent-leborgne
force-pushed
the
feature/hub-card-explore
branch
from
August 11, 2026 15:48
a8a4319 to
bc28c12
Compare
florent-leborgne
force-pushed
the
feature/hub-card-explore
branch
from
August 11, 2026 16:51
bc28c12 to
1ba5e1d
Compare
florent-leborgne
added a commit
that referenced
this pull request
Aug 12, 2026
Martijn's review on #3826. - Card link lists and column link lists take the site's standard link affordance: a bullet, blue, underlined. The leading chevron is gone. An arrow now means a control that behaves like a button, such as a hero action, rather than an entry in a link index. - The aside cluster takes the {button} directive's secondary treatment in a new small size, because those are buttons rather than cards. The size modifier composes with either button type and is available to any caller. - Only a card that carries its own link lifts on hover, and that card now has a whole-card target. A card holding several links and no link of its own no longer promises a click it cannot answer. - Card and explore type moves onto the site's scale. - Explore accordions no longer share a `name`, so a reader can hold several open and compare them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
florent-leborgne
force-pushed
the
feature/hub-card-explore
branch
from
August 12, 2026 18:53
1ba5e1d to
526ee02
Compare
florent-leborgne
added a commit
that referenced
this pull request
Aug 12, 2026
Martijn's review on #3826. - Card link lists and column link lists take the site's standard link affordance: a bullet, blue, underlined. The leading chevron is gone. An arrow now means a control that behaves like a button, such as a hero action, rather than an entry in a link index. - The aside cluster takes the {button} directive's secondary treatment in a new small size, because those are buttons rather than cards. The size modifier composes with either button type and is available to any caller. - Only a card that carries its own link lifts on hover, and that card now has a whole-card target. A card holding several links and no link of its own no longer promises a click it cannot answer. - Card and explore type moves onto the site's scale. - Explore accordions no longer share a `name`, so a reader can hold several open and compare them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
florent-leborgne
force-pushed
the
feature/hub-card-explore
branch
from
August 12, 2026 19:03
526ee02 to
a31286a
Compare
florent-leborgne
added a commit
that referenced
this pull request
Aug 13, 2026
Martijn's review on #3826. - Card link lists and column link lists take the site's standard link affordance: a bullet, blue, underlined. The leading chevron is gone. An arrow now means a control that behaves like a button, such as a hero action, rather than an entry in a link index. - The aside cluster takes the {button} directive's secondary treatment in a new small size, because those are buttons rather than cards. The size modifier composes with either button type and is available to any caller. - Only a card that carries its own link lifts on hover, and that card now has a whole-card target. A card holding several links and no link of its own no longer promises a click it cannot answer. - Card and explore type moves onto the site's scale. - Explore accordions no longer share a `name`, so a reader can hold several open and compare them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
florent-leborgne
force-pushed
the
feature/hub-card-explore
branch
2 times, most recently
from
August 13, 2026 08:34
5db6d7e to
3021075
Compare
florent-leborgne
added a commit
that referenced
this pull request
Aug 13, 2026
Martijn's review on #3826. - Card link lists and column link lists take the site's standard link affordance: a bullet, blue, underlined. The leading chevron is gone. An arrow now means a control that behaves like a button, such as a hero action, rather than an entry in a link index. - The aside cluster takes the {button} directive's secondary treatment in a new small size, because those are buttons rather than cards. The size modifier composes with either button type and is available to any caller. - Only a card that carries its own link lifts on hover, and that card now has a whole-card target. A card holding several links and no link of its own no longer promises a click it cannot answer. - Card and explore type moves onto the site's scale. - Explore accordions no longer share a `name`, so a reader can hold several open and compare them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
florent-leborgne
force-pushed
the
feature/hub-card-explore
branch
from
August 13, 2026 09:38
3021075 to
c2b6ac2
Compare
Mpdreamz
approved these changes
Aug 13, 2026
These three ship together because {explore} is what switches the other two into
their second rendering mode. A reviewer cannot judge the mechanism from any one
of them alone.
{card-group} is a section heading and a card grid. {link-card} is one card, with
a title, a description, a primary link list, and an optional aside. Its body is a
fixed YAML schema rather than markdown, so a missing title or invalid YAML fails
the build. {explore} wraps card groups into a stack of collapsible accordions.
Nesting drives the mode switch, not an option. Inside {explore} a card group
renders as an accordion and a link card renders as a titled link column, with the
description dropped and the aside rendered as a badge cluster under its own
authored label. Driving this from the ancestor rather than a per-directive option
means every card grid elsewhere on the site keeps working unchanged.
Adds HubDirectiveViewModel, which centralises the attributes a hub link needs.
Hub links come from options and YAML bodies, so they never pass through Markdig's
link renderer and each view was repeating the external, anchor, and preload rules
by hand. {hero} moves onto it too.
The LLM export keeps the whole structure. The curated grouping of links is what a
hub page is for, and the nav tree in llms.txt is neither ordered nor curated, so
it is not a substitute. The search body deliberately gets nothing from these three
directives: section, card, and link titles are the tokens that would let a hub
outrank the pages it links to on a specific query.
Adds doesNotContainHtml to the authoring assertions, for content a directive
drops on purpose.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Martijn's review on #3826. - Card link lists and column link lists take the site's standard link affordance: a bullet, blue, underlined. The leading chevron is gone. An arrow now means a control that behaves like a button, such as a hero action, rather than an entry in a link index. - The aside cluster takes the {button} directive's secondary treatment in a new small size, because those are buttons rather than cards. The size modifier composes with either button type and is available to any caller. - Only a card that carries its own link lifts on hover, and that card now has a whole-card target. A card holding several links and no link of its own no longer promises a click it cannot answer. - Card and explore type moves onto the site's scale. - Explore accordions no longer share a `name`, so a reader can hold several open and compare them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Martijn's point about tiny fonts applies to every piece of hub text. Card descriptions, column descriptions, and aside links now read at the body size. The two cluster labels sit one step down, so they stay distinct from the column headings beside them, and nothing renders below 14px. The aside buttons keep 14px. They support the column links above them, so they must not outweigh them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The flag only ever drove the arrow, and the shared link attributes do their own anchor check for preloading. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A link card held two kinds of link: a primary list and an aside that rendered as a badge cluster in a column, or as inline dot-separated links in a card. That is two visual languages for the same thing, in one card. The aside also could not express what it promised. It said "these are secondary", and the only signal was its label. At 12px that label was too small to read, and at 14px it was indistinguishable from the column heading beside it. There is no size that reads as subordinate but legible. A second group of links now becomes a second card. One shape, one treatment, everywhere. This removes the `aside` field, both of its renderings, the badge styling, and the small button size added for it, which nothing else used. It also removes the label sizing question and the sub-24px target on the badges. Follow-ups: elastic/docs-content-internal#1385 and #1549 both specify `aside` and need updating. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
florent-leborgne
force-pushed
the
feature/hub-card-explore
branch
from
August 13, 2026 15:56
0695e66 to
9a8b77a
Compare
The hover border moved from grey-20 to grey-30, a change from 1.22:1 to
1.49:1 against white. That is not a visible state change, and a state
indicator has to clear 3:1. It now uses grey-80 at 4.15:1, which is what
{page-card} already uses for the same job.
The resting border stays grey-20. It is a container edge rather than the
thing that identifies the control, and {page-card} rests there too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The explore stack lost its max-width, so the accordion rows ran the full content column while the section heading above them stayed within the shared width. The rows started well left of their own heading. The rule was collateral damage when the aside styling was removed: the deleted range ran past the aside block and took the container with it. The accordion also drops its horizontal padding, so a title starts on the same line as the section heading and the toggle icon ends on the same line as its right edge. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
florent-leborgne
marked this pull request as ready for review
August 14, 2026 09:10
yetanothertw
pushed a commit
that referenced
this pull request
Aug 14, 2026
* Add {card-group}, {link-card}, and {explore}
These three ship together because {explore} is what switches the other two into
their second rendering mode. A reviewer cannot judge the mechanism from any one
of them alone.
{card-group} is a section heading and a card grid. {link-card} is one card, with
a title, a description, a primary link list, and an optional aside. Its body is a
fixed YAML schema rather than markdown, so a missing title or invalid YAML fails
the build. {explore} wraps card groups into a stack of collapsible accordions.
Nesting drives the mode switch, not an option. Inside {explore} a card group
renders as an accordion and a link card renders as a titled link column, with the
description dropped and the aside rendered as a badge cluster under its own
authored label. Driving this from the ancestor rather than a per-directive option
means every card grid elsewhere on the site keeps working unchanged.
Adds HubDirectiveViewModel, which centralises the attributes a hub link needs.
Hub links come from options and YAML bodies, so they never pass through Markdig's
link renderer and each view was repeating the external, anchor, and preload rules
by hand. {hero} moves onto it too.
The LLM export keeps the whole structure. The curated grouping of links is what a
hub page is for, and the nav tree in llms.txt is neither ordered nor curated, so
it is not a substitute. The search body deliberately gets nothing from these three
directives: section, card, and link titles are the tokens that would let a hub
outrank the pages it links to on a specific query.
Adds doesNotContainHtml to the authoring assertions, for content a directive
drops on purpose.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Apply review feedback to cards and the explore section
Martijn's review on #3826.
- Card link lists and column link lists take the site's standard link
affordance: a bullet, blue, underlined. The leading chevron is gone. An
arrow now means a control that behaves like a button, such as a hero
action, rather than an entry in a link index.
- The aside cluster takes the {button} directive's secondary treatment in a
new small size, because those are buttons rather than cards. The size
modifier composes with either button type and is available to any caller.
- Only a card that carries its own link lifts on hover, and that card now
has a whole-card target. A card holding several links and no link of its
own no longer promises a click it cannot answer.
- Card and explore type moves onto the site's scale.
- Explore accordions no longer share a `name`, so a reader can hold several
open and compare them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Raise card and explore text to body size
Martijn's point about tiny fonts applies to every piece of hub text. Card
descriptions, column descriptions, and aside links now read at the body
size. The two cluster labels sit one step down, so they stay distinct from
the column headings beside them, and nothing renders below 14px.
The aside buttons keep 14px. They support the column links above them, so
they must not outweigh them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Drop the now unused anchor flag on a hero action
The flag only ever drove the arrow, and the shared link attributes do their
own anchor check for preloading.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Drop the aside from a link card
A link card held two kinds of link: a primary list and an aside that
rendered as a badge cluster in a column, or as inline dot-separated links in
a card. That is two visual languages for the same thing, in one card.
The aside also could not express what it promised. It said "these are
secondary", and the only signal was its label. At 12px that label was too
small to read, and at 14px it was indistinguishable from the column heading
beside it. There is no size that reads as subordinate but legible.
A second group of links now becomes a second card. One shape, one
treatment, everywhere.
This removes the `aside` field, both of its renderings, the badge styling,
and the small button size added for it, which nothing else used. It also
removes the label sizing question and the sub-24px target on the badges.
Follow-ups: elastic/docs-content-internal#1385 and #1549 both specify
`aside` and need updating.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Make the linked card's hover state visible
The hover border moved from grey-20 to grey-30, a change from 1.22:1 to
1.49:1 against white. That is not a visible state change, and a state
indicator has to clear 3:1. It now uses grey-80 at 4.15:1, which is what
{page-card} already uses for the same job.
The resting border stays grey-20. It is a container edge rather than the
thing that identifies the control, and {page-card} rests there too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Restore the explore container width
The explore stack lost its max-width, so the accordion rows ran the full
content column while the section heading above them stayed within the
shared width. The rows started well left of their own heading.
The rule was collateral damage when the aside styling was removed: the
deleted range ran past the aside block and took the container with it.
The accordion also drops its horizontal padding, so a title starts on the
same line as the section heading and the toggle icon ends on the same line
as its right edge.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 2 of 4, based on #3825. Implements elastic/docs-content-internal#1384 (
{card-group}), #1385 ({link-card}) and #1549 ({explore}).Demo: https://docs-v3-preview.elastic.dev/elastic/docs-builder/pull/3826/examples/products/docs-builder
The three ship together because
{explore}is what switches the other two into their second rendering mode. Split apart, this would add a mode switch nothing can trigger.The mode switch
Nesting decides it. There is no option.
{explore}{card-group}{link-card}Driving this from the ancestor rather than a per-directive option means every card grid elsewhere on the site keeps working unchanged. An author wraps existing groups in
{explore}and the rendering follows.The first accordion in a stack is expanded and the rest are collapsed. Toggling uses native
<details>and<summary>, so it works without JavaScript.Implementation choices
HubDirectiveViewModel. Hub links come from directive options and YAML bodies, so they never reach Markdig's link renderer.{link-card}alone has six anchors, and each view was repeating the external, anchor and preload rules by hand. This centralises them into oneLinkAttributescall.{hero}moves onto it too.Heading levels. An accordion title renders as
<h3>and a column title as<h4>, so an Explore stack keeps a complete outline: sectionh2, accordionh3, columnh4. A<span>would leave the accordion group missing from the page outline.Machine-readable output. The LLM export keeps the whole structure, because the curated grouping of links is what a hub page is for. The search body deliberately gets nothing from these three: section, card and link titles are the tokens that would let a hub outrank the pages it links to.
From the designs
aside, a second list of links inside a card, is dropped. A card held two kinds of link, which meant two treatments for the same thing in one card. A second group of links is now a second card. elastic/docs-content-internal#1385 and Clarify mandatory link text #1549 are updated.{page-card}, so every card on the page that is a link behaves the same way.Example page
docs/examples/products/docs-builder.mdgrows from a hero into a full hub, exercising every mode: a standalone highlight grid, a:variant: solutionsgrid with icons and accent variants, and a three-accordion{explore}stack of link columns.Its solution cards use
docs-content://cross-links to the published Elastic documentation, which also covers the cross-link form.Testing
./build.sh unit-testpasses.dotnet formatandnpm run fmt:checkare clean. A full docs build reports 0 errors and 0 warnings.tests/authoring/Blocks/Hub/CardsAndExplore.fscovers both rendering modes, thesolutionsvariant, the first-accordion-open rule, the dropped description, the heading levels, icon and variant accents, and four failure paths.Screenshots to add or update
None attached. The accordion stack and the two card layouts are worth checking on the preview.