Skip to content

Blog: add quotes shortcode for testimonial cards - #3141

Merged
localden merged 6 commits into
mainfrom
feat/quote-component
Jul 27, 2026
Merged

Blog: add quotes shortcode for testimonial cards#3141
localden merged 6 commits into
mainfrom
feat/quote-component

Conversation

@claude

@claude claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Requested by Den Delimarsky · Slack thread

Before / After

Before: customer quotes in blog posts render as plain markdown blockquotes, a gray bar with indented text.

After: quotes render as a horizontal strip of cards in the style of the claude.com blog. The strip breaks out of the post's text column and bleeds toward the viewport edges, up to 1200px wide, centered, three cards per view on desktop. Each card shows the company logo, the quote in body type wrapped in typographic quotation marks, and a two-line attribution with the person's name in bold and their title in muted regular type on the line below, with hairline dividers between cards. Quotes can run long: text spills downward without clamping, and every attribution in the set starts on the same line, sized by the longest quote, on every carousel page. Attributions that wrap do so below that shared line. When more quotes exist than fit one view, cards narrow slightly so a slice of the next card peeks at the right edge, and arrow buttons and pagination dots appear under the strip. A lone quote renders as a pull quote that stays in the text column. The strip shrinks back to the column width on narrow screens, with one card per view and a small peek on mobile, and everything follows the blog's light and dark themes.

Usage

Nothing to install. The two shortcodes and the stylesheet ship with the blog once this merges, and Hugo picks them up automatically.

To add quotes to a post:

  1. Make the post a page bundle if it is not one already: a directory with an index.md inside, for example blog/content/posts/my-post/index.md.
  2. Put each company's SVG logo in that directory next to index.md. Bundle SVGs are inlined into the page, so wordmarks that use currentColor adapt to light and dark automatically.
  3. Add a quotes block where the cards should appear, with one quote per card:
{{< quotes >}}
{{< quote name="Ada Person" title="CTO" company="Acme" logo="acme-logo.svg" >}}
Quote text goes here. Markdown is supported.
{{< /quote >}}
{{< /quotes >}}

Parameters on quote:

  • name: the person's name, shown in bold.
  • title: the person's role, shown in muted type on its own line under the name. Optional. Without it the attribution is the name alone.
  • company: the company name. It labels the logo for screen readers and renders as a text wordmark when no logo is given.
  • logo: filename of an SVG in the post's page bundle. A path outside the bundle still renders, but as a plain img tag that keeps its hardcoded colors in both themes. Omit it to fall back to the text wordmark.

Layout comes for free. Three cards per view on desktop, two at medium widths, one on mobile, with a slice of the next card peeking at the right edge when more quotes exist than fit. Arrow buttons and pagination dots appear only when the quotes overflow one view. A single quote renders as a full-width pull quote that stays in the text column.

How

Two Hugo shortcodes plus a stylesheet:

  • blog/layouts/shortcodes/quotes.html wraps the cards in a CSS scroll-snap track and carries a small vanilla JS snippet (emitted once per page, initialized after DOMContentLoaded so every quotes block on a page gets controls) that shows the arrows and dots only when the quotes overflow one view. No dependencies added.
  • blog/layouts/shortcodes/quote.html renders one card. SVG logos from the post's page bundle are inlined, so currentColor wordmarks track the theme. Non-bundle paths fall back to an img tag, and omitting logo renders the company name as a text wordmark.
  • blog/assets/css/extended/quotes.css styles the cards with the blog's existing CSS variables. The breakout is symmetric negative margins on the strip, capped at min((1200px - 100%) / 2, 50vw - 50% - 32px) per side. The 32px gutter absorbs the page scrollbar that 100vw includes, so the page never gains a horizontal scrollbar. The attribution start line is pure CSS: the track defines logo, quote, and attribution rows, and each card adopts them with grid-template-rows: subgrid (Chrome and Edge 117+, Firefox 71+, Safari 16+). Browsers without subgrid fall back to the previous flex layout, where attributions align to the card bottom instead.

Reviewers can see the component rendered in this PR's earlier preview deployments or by adding the shortcode block above to any post locally.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YWbYcGYDQESh3KWwpfoc4V

Adds a quotes/quote shortcode pair that renders testimonial cards in a
row with hairline dividers, matching the docs site's design language.
When more quotes than fit one view are given, a scroll-snap carousel
with arrow buttons and pagination dots takes over. A lone quote renders
full width as a pull quote.

Includes a draft test post with fictional companies and original SVG
wordmarks so the component can be reviewed in the PR preview. Drop the
test post before or at merge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWbYcGYDQESh3KWwpfoc4V
@github-actions github-actions Bot added the blog label Jul 27, 2026
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Preview

Preview deployments for this PR have been cleaned up.

claude added 5 commits July 27, 2026 17:50
Cards in a quotes row now adopt the track's explicit logo, quote, and
attribution rows via CSS subgrid, so every attribution starts at the same
line across a row and across carousel pages. Long quotes spill downward
without clamping and short cards keep the open space. Attributions that
wrap do so below the shared line. Browsers without subgrid fall back to
the previous bottom-aligned flex layout. Subgrid is skipped below 600px
where cards render one per view. Test post quotes now vary in length to
show the behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWbYcGYDQESh3KWwpfoc4V
The quotes row now bleeds horizontally past the post column, capped at
1200px and centered in the viewport, with a slice of the next card
peeking at the right edge whenever more cards exist than fit one view.
The bleed bound leaves a 32px gutter that absorbs the page scrollbar,
so the page never scrolls horizontally. Carousel init now waits for
DOMContentLoaded so every quotes block on a page gets its controls,
and the arrow disabled state follows the actual scroll position.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWbYcGYDQESh3KWwpfoc4V
PaperMod bolds figure > figcaption, which made the Name, Title line
read too heavy. Override it to font-weight 400 so the attribution is a
quiet secondary line, and drop the 600 weight on the no-logo company
name fallback to match.
The figcaption now renders the name and title as separate block spans
instead of one "Name, Title" line. The name is 700 in the body text
color, the title stays 400 in the muted secondary color. A quote with
no title renders the name alone. The test post gains a no-title
variant to exercise that path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWbYcGYDQESh3KWwpfoc4V
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWbYcGYDQESh3KWwpfoc4V
@claude
claude Bot marked this pull request as ready for review July 27, 2026 22:20
@claude
claude Bot requested review from dsp-ant and localden as code owners July 27, 2026 22:20
@localden
localden merged commit 7d6c7b8 into main Jul 27, 2026
9 checks passed
@localden
localden deleted the feat/quote-component branch July 27, 2026 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants