Skip to content

DirectorySkills

Masonry quote wall: 1440, made in this run
Run 1Masonry quote wall“We have loads of customer messages. Make a wall of them for our candle shop homepage. See brief.md.”
Runs in
  • Claude Code
  • Codex
  • Cursor
  • Gemini CLI
  • GitHub Copilot
  • OpenCode
Generates with
Your agent's model
Tested with
Claude Code 2.1.322Claude Sonnet 5.51 real run, 12 Nov
Needs
Node 20+Chrome
Licence
Recaply licence

Masonry Quote Wall

A masonry wall of many quote cards of different lengths that fades out at the bottom, with a Show all button.

1 view

$9.99once, yours to keep

Builds a masonry wall of testimonials with a show-more control into your own project: twelve quote cards of different lengths in three masonry columns on warm white, the wall cut at 640px with a fade to the background and a Show all 12 button that opens it fully. Plain HTML, CSS and JavaScript, or matched to React, Next.js, Vue, Svelte, Astro or Tailwind when the project uses them. Comes with a working reference and a check that screenshots it at phone, tablet and desktop widths and flags sideways overflow, text under 12px, missing alt text and names, low contrast, no focus styles, motion that ignores reduced motion, leftover sample words and emoji icons. Use when a product with many testimonials wants to show volume without a long page, or someone asks for a masonry, wall-of-love or Pinterest-style testimonial wall.

By RecaplyUpdated 12 Nov

Install Masonry Quote Wall

After the download, ask your agent to add it, or run the line yourself.

Read https://recaply.co/skills/quote-wall/install.md and follow it to install the quote-wall skill from quote-wall.zip.

Paste it into your agent. It reads our install steps, finds the ZIP you downloaded and adds the skill for you.

New to skills? How to install a skill

Similar skills

All 735 skills

Who Masonry Quote Wall is for

What you get

  • One HTML file with its CSS inside: no build step, no framework
  • A masonry wall of testimonials with a show-more control
  • Checked at phone and desktop widths

Good fit

  • When a product with many testimonials wants to show volume without a long page

Not for

  • An app with a backend, sign-in or a database
  • Copying another company's site

About this skill

You say

We have loads of customer messages. Make a wall of them for our candle shop homepage. See brief.md.

It said back

The wall is built and passes the check. It shows about six cards, and a "Show all 15" button opens the rest.

All 15 reviews are in as written, each with the first name and candle from your brief. The page is one section of the homepage. It has a centred heading and three columns on desktop, two on tablet and one on phone, and it passes at 390, 768 and 1440px. The check found no overflow, small text, contrast or focus problems. I read all three screenshots. The open state ("Show fewer") isn't in the screenshots, and I didn't click it in a browser.

Show more

What it did in run 1

  1. quote-wall
  2. ./brief.md
  3. cd .; ls -a; S=.claude/skills/quote-wall; ls $S/reference; cat $S/reference/index.html $S/reference/style.css $S/reference/script.js
  4. ls -a && cat .claude/skills/quote-wall/reference/index.html .claude/skills/quote-wall/reference/style.css .claude/skills/quote-wall/reference/script.js
  5. mkdir -p ../gen-work1 && cat > ../gen-work1/gen.mjs <<'EOF' import fs from 'node:fs'; const q=[ ["It smells like a walk in the woods after rain. I've bought four.","Harriet","Fern & Moss"], ["Burned for 52 hours, and the scent lasted to the end.","Dev","Cedar Smoke"], ["My mum cried when she opened it. It smells like her garden.","Olivia","Rose & Rhubarb"], ["Clean burn, no black soot on the jar.","Marcus","Sea Salt & Sage"], ["The only candle my husband has ever commented on.","Priya","Fig Leaf"], ["Lovely gift box. It arrived the next day.","Tom","Winter Orchard"], ["Subtle, not overpowering. Perfect for a small flat.","Anya","Linen & Lavender"], ["I light it when I start work and blow it out when I stop.","Callum","Coffee & Cardamom"], ["The cotton wick crackles a little. I love that.","Ruth","Ember & Oak"], ["Smells exactly like Christmas Eve at my gran's.","Sinead","Clove & Orange"], ["Third order this year. The refill was easy too.","James","Cedar Smoke"], ["Sat in my bath with this and forgot about the week.","Leila","Linen & Lavender"], ["Bought one, then went back for two more as gifts.","Owen","Fern & Moss"], ["Not too sweet, which is rare for a vanilla.","Grace","Vanilla Bark"], ["Even the empty jar is now a pen pot on my desk.","Ben","Sea Salt & Sage"]]; const e=s=>s.replace(/&/g,'&amp;').replace(/'/g,'&#39;'); const li=q.map(([t,n,c],i)=><li class="qw-c t${i%4+1}"><figure><blockquote><p>${e(t)}</p></blockquote><figcaption class="who"><span class="face" aria-hidden="true">${n[0]}</span><span><b>${n}</b><span class="role">${e(c)}</span></span></figcaption></figure></li>).join('\n'); fs.writeFileSync('index.html',<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Kind words from our customers | Wick &amp; Hollow candles</title> <meta name="description" content="Fifteen reviews from Wick &amp; Hollow customers, shared with permission."> <meta property="og:title" content="Kind words from our customers | Wick &amp; Hollow"> <meta property="og:description" content="Fifteen reviews from Wick &amp; Hollow customers, shared with permission."> <meta property="og:type" content="website"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700&display=swap"> <link rel="stylesheet" href="style.css"> </head> <body> <a class="skip" href="#main">Skip to content</a> <main id="main"> <section class="t-sec" id="wall" aria-labelledby="wall-h"><div class="sec-head center"><h2 id="wall-h">Kind words from <em>our customers</em></h2><p class="sub">Fifteen notes from people who lit a Wick &amp; Hollow candle, shared with their permission.</p></div><div class="wrap"><div class="qw closed" id="qw-list"><ul class="qw-cols"> ${li} </ul></div><p class="qw-more"><button class="btn btn-primary" type="button" aria-expanded="false" aria-controls="qw-list" data-qw>Show all 15</button></p></div></section> </main> <script src="script.js" defer></script> </body> </html> ); EOF node ../gen-work1/gen.mjs R=.claude/skills/quote-wall/reference python3 - <<'EOF' import re r='.claude/skills/quote-wall/reference/' c=open(r+'style.css').read() c=c.split('/* this design */')[0] for k,v in {'--bg:#FFFBF5':'--bg:#FAF6EA','--ink:#24201C':'--ink:#232820','--muted:#5E574F':'--muted:#59604F','--line:#EFE5D6':'--line:#E3DCC6','--accent:#C2412D':'--accent:#44684A','--em:#B23A27':'--em:#3D5F43','--t1:#FFF1E6':'--t1:#F3EAD3','--t2:#EEF6EC':'--t2:#E4EDDD','--t3:#EEF1FA':'--t3:#EDF1E3','--t4:#FBEFF4':'--t4:#F7F0DF'}.items(): c=c.replace(k,v) c=c.replace('.js .reveal{opacity:0;transform:translateY(18px);transition:opacity .7s ease,transform .7s ease}\n.js .reveal.in{opacity:1;transform:none}\n','') c=c.replace('.js .reveal{opacity:1;transform:none}','') c+='''/* this design */ .qw{--closed:430px;position:relative;overflow:hidden;transition:max-height .5s ease} .qw.closed{max-height:var(--closed)} .qw.closed::after{content:"";position:absolute;left:0;right:0;bottom:0;height:130px;background:linear-gradient(transparent,var(--bg));pointer-events:none} .qw-cols{columns:3;column-gap:16px} .qw-c{break-inside:avoid;margin-bottom:16px;border-radius:18px;padding:1.3rem} .qw-c figure{display:flex;flex-direction:column;gap:1rem} .qw-c blockquote p{font-size:1rem} .t1{background:var(--t1)}.t2{background:var(--t2)}.t3{background:var(--t3)}.t4{background:var(--t4)} .qw-c .face{width:40px;height:40px;display:grid;place-items:center;background:var(--accent);color:var(--on-accent);font-weight:700;font-size:1rem} .qw-more{text-align:center;margin-top:1.4rem} .qw .qw-cols{padding-bottom:1px} @media (max-width:1000px){.qw{--closed:600px}.qw-cols{columns:2}} @media (max-width:760px){.qw{--closed:860px}.qw-cols{columns:1}.btn{min-height:48px}} ''' open('style.css','w').write(c) EOF cat > script.js <<'EOF' // Opens and closes the wall. const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)'); const qw = document.getElementById('qw-list'); const qb = document.querySelector('[data-qw]'); const total = qw.querySelectorAll('.qw-c').length; const closedHeight = () => parseFloat(getComputedStyle(qw).getPropertyValue('--closed')); qb.addEventListener('click', () => { const open = qb.getAttribute('aria-expanded') !== 'true'; qb.setAttribute('aria-expanded', String(open)); qb.textContent = open ? 'Show fewer' : 'Show all ' + total; if (open) { qw.style.maxHeight = closedHeight() + 'px'; qw.classList.remove('closed'); void qw.offsetHeight; qw.style.maxHeight = qw.scrollHeight + 'px'; setTimeout(() => { if (qb.getAttribute('aria-expanded') === 'true') qw.style.maxHeight = 'none'; }, reduceMotion.matches ? 0 : 520); } else { qw.style.maxHeight = qw.scrollHeight + 'px'; void qw.offsetHeight; qw.classList.add('closed'); qw.style.maxHeight = ''; if (qw.getBoundingClientRect().top < 0) qw.scrollIntoView({ behavior: reduceMotion.matches ? 'auto' : 'smooth' }); } }); EOF node .claude/skills/quote-wall/scripts/check.mjs index.html --out check 2>&1 | tail -40
  6. /private/var/folders/4r/x1k_d3dx36v_yrnn39ymflm40000gn/T/rcl-real-runs/quote-wall/gen-work1/gen.mjs
  7. ./script.js
  8. node ../gen-work1/gen.mjs . && head -c 1700 .claude/skills/quote-wall/reference/style.css | head -3 | cut -c1-40
  9. ./style.css
  10. node .claude/skills/quote-wall/scripts/check.mjs index.html --out check 2>&1 | tail -40
  11. ./check/1440.png
  12. ./check/390.png
  13. ./check/768.png
  14. Done

12 Nov 2026 · Claude Code 2.1.322 with Claude Sonnet 5.5 · 1 min 16 s · $0.26 of API use

Questions

Is Masonry Quote Wall free?

No. Masonry Quote Wall costs $9.99 once and stays in your Recaply account, or it comes with the Recaply plan ($19.99 a month), which opens every premium skill and prompt.

Which agents can use Masonry Quote Wall?

Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.

What do I get when I buy Masonry Quote Wall?

A ZIP of the whole skill folder (32 KB): the SKILL.md your agent follows and its 6 other files, the references, templates and scripts it uses. You download it from this page whenever you need it, and install it in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode. The Recaply plan opens it too, with every other premium skill and prompt.

How do I install Masonry Quote Wall?

Buy it, then download the ZIP from this page. For Claude Code, unzip it into .claude/skills/ in your project. For Codex, Cursor and Gemini CLI, unzip it and run npx skills add ./quote-wall with your agent's flag.

What do I get from Masonry Quote Wall?

One HTML file with its CSS inside: no build step, no framework. A masonry wall of testimonials with a show-more control. Checked at phone and desktop widths.

What does Masonry Quote Wall need?

Node 20+ and Chrome, and no API key. Each use costs nothing beyond your agent.

How big is Masonry Quote Wall?

7 files, about 22,490 tokens in all. The SKILL.md is about 2,160 tokens, and your agent reads it only when the job fits.

What does a run cost?

Our 1 runs took 1 min 16 s to 1 min 16 s and $0.26 to $0.26 of API use each, in Claude Code with claude-sonnet-5-5. On a Claude plan, a run counts toward your usage instead.

Do I have to name Masonry Quote Wall to use it?

Type /quote-wall first to make sure it loads. Without it, Claude Code may judge a small job simple enough to do without the skill.