Video
![]()
![]()
Editorial hero for a report








A calm navy-and-sand SaaS site: product hero, feature bento, proof, and its own pricing page.
$9.99once, yours to keep
Payments are non-refundable. See our Terms of service.
Yours. Download it, then add it to your agent.
Builds a two-page SaaS site (home and pricing) in a calm nautical style into your own project: sand-coloured pages, deep navy type in a fine serif, signal-orange accents and rope-dashed rules; a home page with a product hero, customer names, a feature bento, figures and quotes, plus a pricing page with a monthly/yearly switch and questions. 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 software product needs a trustworthy marketing site with a home page and a pricing page, or someone asks for a calm, navy, maritime-feeling SaaS site.
By RecaplyUpdated 12 Nov
Video
![]()
![]()
Editorial hero for a report
Video1 view, 0 downloads
![]()
![]()
Lavender page for an AI app
Video
![]()
![]()
Product page for headphones
Video
![]()
![]()
Page with a node-flow hero
You say
Make a marketing site for our product, Shiftlog, with a home page and a pricing page. The details are in brief.md.
It said back
I've built the Shiftlog site as plain HTML and CSS: a home page and a pricing page. I ran the skill's check on both pages at 390, 768 and 1440px wide, and it passed. It looks for sideways overflow, small text, missing alt text and names, contrast, focus styles, reduced-motion handling and script errors. I looked at the 1440 and 390 screenshots of the home page and the 1440 screenshot of the pricing page. I didn't look at the 768 screenshots, or at the pricing page at 390.
Files (in the project folder)
index.html has the hero with a drawn handover screen, a four-card feature grid, and a closing "book a demo" block.pricing.html has three plan cards (Ward, Hospital, Trust), four questions that open and close, and the same closing block.style.css and script.js are the design's styles and behaviour. I added one rule to style.css so the demo button shows on the navy block.check/ and check-pricing/.What it did in run 1
<svg viewBox="0 0 32 32" aria-hidden="true" focusable="false"><rect width="32" height="32" rx="9" fill="#0E2A47"/><path d="M5 18c4-5 7-5 11 0s7 5 11 0" stroke="#F6F2EA" stroke-width="3" fill="none" stroke-linecap="round"/></svg>; const ic = (d) => <svg class="ic" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="${d}"/></svg>; const arrow = ic('M5 12h14M13 6l6 6-6 6'); const tick = ic('M5 12l5 5 9-10'); const plus = ic('M12 5v14M5 12h14'); const head = (title, desc) => <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>${title}</title> <meta name="description" content="${desc}"> <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=Instrument+Serif:ital@0;1&family=Instrument+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="style.css"> </head> <body> <a class="skip" href="#main">Skip to content</a> <header class="nav nav-bar"><div class="wrap nav-in"> <a class="brand" href="index.html" aria-label="Shiftlog home">${brandSvg}<span>Shiftlog</span></a> <button class="nav-toggle" type="button" data-nav-toggle aria-expanded="false" aria-controls="menu">${ic('M4 7h16M4 12h16M4 17h16')}<span class="sr-only">Menu</span></button> <nav id="menu" class="menu" aria-label="Main"><ul><li><a href="index.html#features">Product</a></li><li><a href="pricing.html">Pricing</a></li></ul><a class="btn btn-primary btn-sm" href="#cta">Book a demo</a></nav> </div></header> <main id="main"> ; const cta = (h, p) => <section class="sec cta cta-band" id="cta" aria-labelledby="cta-h"><div class="wrap"><div class="cta-box reveal"><h2 id="cta-h">${h}</h2><p>${p}</p> <!-- TODO: connect this form to your own demo-request handler. Until then it only shows the confirmation message and sends nothing. --> <form class="inline-form" data-form data-done="Thanks. We'll be in touch to arrange your demo." novalidate><label class="sr-only" for="demo-email-${'x'}">Work email</label><input id="demo-email-x" type="email" name="email" autocomplete="email" placeholder="Work email" required><button class="btn btn-primary" type="submit">Book a demo</button><p class="form-status" role="status" aria-live="polite"></p></form></div></div></section> ; const foot = </main> <footer class="foot"><div class="wrap foot-in"><div class="foot-brand"><a class="brand" href="index.html">${brandSvg}<span>Shiftlog</span></a><p>Shared handover notes for hospital ward teams.</p></div><nav class="foot-col" aria-label="Product"><h2>Product</h2><ul><li><a href="index.html#features">Features</a></li><li><a href="pricing.html">Pricing</a></li><li><a href="#cta">Book a demo</a></li></ul></nav></div><div class="wrap foot-small"><p>© <span data-year>2026</span> Shiftlog</p></div></footer> <script src="script.js" defer></script> </body> </html> ; const bar = (x,y,w,fill='#D9DCE3',h=7) => <rect x="${x}" y="${y}" width="${w}" height="${h}" rx="${h/2}" fill="${fill}"/>; const chrome = <rect width="640" height="420" rx="14" fill="#FFFFFF"/><path d="M0 14a14 14 0 0 1 14-14h612a14 14 0 0 1 14 14v20H0z" fill="#F3EFE6"/><circle cx="20" cy="17" r="5.5" fill="#FF6B5E"/><circle cx="38" cy="17" r="5.5" fill="#FFC23D"/><circle cx="56" cy="17" r="5.5" fill="#2ACB55"/>; // hero: handover list with read receipts let rows = ''; const widths = [250, 310, 210, 280, 190]; for (let i = 0; i < 5; i++) { const y = 112 + i * 56; rows += <rect x="190" y="${y}" width="414" height="44" rx="8" fill="#F3EFE6"/> + bar(206, y + 12, widths[i], '#C9CDD6', 8) + bar(206, y + 27, widths[i] - 80, '#D9DCE3', 6) + <circle cx="580" cy="${y + 22}" r="9" fill="${i < 3 ? '#0E2A47' : 'none'}" stroke="#0E2A47" stroke-width="1.6"/> + (i < 3 ? <path d="M575 ${y + 22}l3.5 3.5 6-7" stroke="#F6F2EA" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/> : ''); } const heroArt = <svg viewBox="0 0 640 420" role="img" aria-label="Shiftlog handover screen: a list of patient notes, each with a read receipt">${chrome}<rect x="20" y="54" width="150" height="346" rx="10" fill="#F3EFE6"/>${bar(36,74,70,'#1F2430',8)}${[0,1,2,3].map(i=><rect x="30" y="${98+i*40}" width="130" height="30" rx="8" fill="${i===1?'#FFFFFF':'none'}"/>+bar(42,109+i*40,[70,86,60,78][i])).join('')}${bar(190,66,180,'#1F2430',14)}<rect x="480" y="62" width="124" height="22" rx="11" fill="#B8441A"/>${rows}</svg>; const art1 = <svg viewBox="0 0 640 420" aria-hidden="true" focusable="false">${chrome}${bar(36,64,260,'#1F2430',16)}${[0,1,2].map(i=>{const y=108+i*94;return <rect x="36" y="${y}" width="568" height="80" rx="10" fill="#F3EFE6"/><rect x="52" y="${y+16}" width="28" height="28" rx="8" fill="${i===1?'#B8441A':'#0E2A47'}" opacity=".9"/>+bar(96,y+18,[200,160,230][i],'#C9CDD6',9)+bar(96,y+38,380,'#D9DCE3')+bar(96,y+54,300,'#D9DCE3');}).join('')}</svg>; const art2 = <svg viewBox="0 0 640 420" aria-hidden="true" focusable="false">${chrome}<path d="M320 70l110 40v90c0 70-48 118-110 146-62-28-110-76-110-146v-90z" fill="#0E2A47"/><path d="M270 205l37 37 66-76" stroke="#F6F2EA" stroke-width="14" fill="none" stroke-linecap="round" stroke-linejoin="round"/>${bar(120,372,400,'#D9DCE3',8)}</svg>; const index = head('Shiftlog: shared handover notes for hospital ward teams', 'Shiftlog gives hospital ward teams shared handover notes with templates, read receipts and offline use on ward tablets.') + <section class="hero hero-product"><div class="wrap hero-in"><div class="hero-words reveal"><p class="kicker">For hospital ward teams</p><h1>Handover that <em>nothing</em> slips through</h1><p class="hero-sub">Shiftlog gives your ward shared handover notes, so the next shift knows what the last one knew, and you can see that they read it.</p><div class="hero-ctas"><a class="btn btn-primary" href="#cta">Book a demo${arrow}</a><a class="btn btn-ghost" href="#features">See what it does</a></div><p class="hero-note">Free for one ward.</p></div><div class="hero-art reveal">${heroArt}</div></div></section> <section class="sec features features-bento" id="features" aria-labelledby="features-h"><div class="wrap"><div class="sec-head"><h2 id="features-h">Everything a shift <em>needs</em></h2><p class="sec-sub">Four things that make a handover dependable.</p></div><ul class="feat-list"> <li class="feat reveal" style="--span:4"><div class="feat-art">${art1}</div><h3>Handover templates</h3><p>Start every handover from the same structure, so nothing important depends on who is writing it.</p></li> <li class="feat reveal" style="--span:2"><span class="feat-ic">${ic('M5 12l5 5 9-10M3 17l1 1M21 7l-4 4')}</span><h3>Read receipts</h3><p>See who has read a handover note, and who has not yet.</p></li> <li class="feat reveal" style="--span:2"><span class="feat-ic">${ic('M4 6h16v10H4zM9 20h6M12 16v4')}</span><h3>Works offline on ward tablets</h3><p>Keep writing and reading when the signal drops.</p></li> <li class="feat reveal" style="--span:4"><div class="feat-art">${art2}</div><h3>NHS-grade security review</h3><p>Shiftlog goes through an NHS-grade security review, so the people who sign off your software have less to chase.</p></li> </ul></div></section> ${cta('Give your next shift a <em>better</em> handover','See Shiftlog on your own ward. Leave your email and we will arrange a demo.')} + foot; const tier = (cls, flag, name, blurb, amount, per, btn, items) => <li class="tier reveal${cls}">${flag ? <p class="tier-flag">${flag}</p> : ''}<h3>${name}</h3><p class="tier-blurb">${blurb}</p><p class="tier-price"><span class="amount">${amount}</span>${per ? <span class="per">${per}</span> : ''}</p>${btn}<ul class="ticks">${items.map(i => <li>${tick}${i}</li>).join('')}</ul></li>; const q = (open, s, a) => <details class="reveal"${open ? ' open' : ''}><summary>${s}${plus}</summary><p>${a}</p></details>; const pricing = head('Pricing | Shiftlog', 'Shiftlog plans: Ward is free for one ward, Hospital is $6 per person a month, Trust is custom.').replace('href="#cta">Book a demo</a>\n</div>', 'href="#cta">Book a demo</a>\n</div>') + <section class="hero hero-center page-head"><div class="wrap hero-in"><h1>Simple plans for <em>every</em> ward</h1><p class="hero-sub">Start with one ward for free. Pay per person when you grow to a hospital, or talk to us about a trust.</p></div></section> <section class="sec pricing" id="pricing" aria-label="Plans"><div class="wrap"><ul class="tiers"> ${tier('', '', 'Ward', 'For a single ward getting started.', 'Free', 'for one ward', '<a class="btn btn-ghost" href="#cta">Book a demo</a>', ['Handover templates', 'Read receipts', 'Works offline on ward tablets'])} ${tier(' featured', 'Most hospitals pick this', 'Hospital', 'For every ward in your hospital.', '$6', '/ person a month', '<a class="btn btn-primary" href="#cta">Book a demo</a>', ['Everything in Ward', 'Use across more than one ward', 'NHS-grade security review'])} ${tier('', '', 'Trust', 'For trusts with larger needs.', 'Custom', '', '<a class="btn btn-ghost" href="#cta">Talk to us</a>', ['Everything in Hospital', 'Pricing and terms agreed with you', 'NHS-grade security review'])} </ul></div></section> <section class="sec faq" id="faq" aria-labelledby="faq-h"><div class="wrap faq-in"><div class="sec-head"><h2 id="faq-h">Questions, answered</h2></div><div class="faq-list"> ${q(true, 'Is Shiftlog really free for a ward?', 'Yes. The Ward plan is free for one ward, with handover templates, read receipts and offline use on ward tablets.')} ${q(false, 'How is the Hospital plan priced?', 'Hospital is $6 per person a month. Book a demo and we will go through how that works for your wards.')} ${q(false, 'Does it work when the wifi drops?', 'Yes. Shiftlog works offline on ward tablets, so handover notes stay available on the ward.')} ${q(false, 'Has Shiftlog been security reviewed?', 'Yes. It goes through an NHS-grade security review. Ask us at a demo for the detail your information governance team needs.')} </div></div></section> ${cta('Not sure which plan <em>fits</em>?', 'Leave your email and we will arrange a demo for your ward or trust.')} + foot; fs.writeFileSync(dir + '/index.html', index); fs.writeFileSync(dir + '/pricing.html', pricing); EOF node /tmp/gen.mjs . && lsNo. Nautical SaaS Site 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.
Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.
A ZIP of the whole skill folder (42 KB): the SKILL.md your agent follows and its 7 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.
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 ./nautical-saas-site with your agent's flag.
One HTML file with its CSS inside: no build step, no framework. A two-page SaaS site (home and pricing) in a calm nautical style. Checked at phone and desktop widths.
Node 20+ and Chrome, and no API key. Each use costs nothing beyond your agent.
8 files, about 32,343 tokens in all. The SKILL.md is about 2,768 tokens, and your agent reads it only when the job fits.
Our 1 runs took 3 min 19 s to 3 min 19 s and $0.53 to $0.53 of API use each, in Claude Code with claude-sonnet-5-5. On a Claude plan, a run counts toward your usage instead.
Type /nautical-saas-site first to make sure it loads. Without it, Claude Code may judge a small job simple enough to do without the skill.