8pt

Floating Folders CTA

Floating Folders CTA•Hero
Overview

A closing call-to-action: centered headline and primary button, surrounded by colorful glass folders that float gently and shift with a subtle parallax as the pointer moves.

Taken from the page template Nook Mac App Website. Use it on its own, or combine it with the other components from the same template to rebuild the full page.

Plain HTML, CSS and a little vanilla JS, with no framework dependency. Copy the prompt into Claude Code, Cursor, Trae or Codex and the model adds Floating Folders CTA to your project in your colors.

Where to use it

The hero of a product site, SaaS landing page or campaign page: where the headline, subhead and primary button make the first impression.

Install

With Builder, install it with the 8pt CLI or call it directly from an editor connected to 8pt MCP.

$ npm i -g @8pt-dev/cli && 8pt add floating-folders-cta
mcp › Use 8pt MCP to call get_component("floating-folders-cta")

Code

Source for Floating Folders CTA. Motion uses only transform and opacity and respects the Reduce motion setting.

<section class="x-ffc">
  <div class="x-ffc__bg" aria-hidden="true"></div>
  <h2><span>Give your files</span><span>a good home.</span></h2>
  <p>Nook Launch price ¥88, regularly ¥148, one-time purchase.</p>
  <a class="x-ffc__btn" href="#" role="button">Buy Nook · ¥88</a>
</section>
.x-ffc{position:relative;isolation:isolate;overflow:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:clamp(10px,3.4cqi,22px);width:100%;height:100%;min-height:220px;padding:24px;box-sizing:border-box;container-type:size;text-align:center;background:var(--d-bg,#09090d);color:var(--d-fg,#fff);font-family:var(--d-font,system-ui,sans-serif)}
.x-ffc h2{margin:0;font-size:clamp(26px,9cqi,72px);font-weight:700;letter-spacing:-.04em;line-height:1.05}
.x-ffc h2 span{display:inline-block}
.x-ffc p{margin:0;font-size:clamp(12px,2.6cqi,17px);color:var(--d-muted,#9b9ba8)}
.x-ffc__btn{display:inline-flex;align-items:center;height:clamp(38px,8cqi,52px);padding:0 clamp(18px,4.4cqi,30px);border-radius:99px;background:var(--d-accent,#4D74FF);color:#fff;font-size:clamp(13px,2.5cqi,16px);font-weight:600;text-decoration:none;box-shadow:0 8px 24px color-mix(in srgb,var(--d-accent,#4D74FF) 40%,transparent);transition:transform .2s}
.x-ffc__btn:hover{transform:translateY(-1px)}.x-ffc__btn:active{transform:scale(.97)}
.x-ffc__btn:focus-visible{outline:2px solid var(--d-accent,#4D74FF);outline-offset:3px}
.x-ffc__bg{position:absolute;inset:0;z-index:-1;pointer-events:none;transform:translate(var(--px,0),var(--py,0));transition:transform .6s cubic-bezier(.16,1,.3,1)}
.x-ffc__f{position:absolute;width:clamp(48px,13cqi,96px);aspect-ratio:96/80;margin:-6% 0 0 -6%;opacity:.6;animation:x-ffc-fl 9s ease-in-out infinite}
.x-ffc__f svg{position:absolute;inset:0;width:100%;height:100%}
.x-ffc__f svg path{fill:color-mix(in srgb,var(--h) 78%,#000)}
.x-ffc__f i{position:absolute;left:3%;right:3%;bottom:1%;height:65%;border-radius:12%/18%;border:1px solid rgba(255,255,255,.7);background:linear-gradient(149deg,color-mix(in srgb,var(--h) 45%,rgba(255,255,255,.6)),color-mix(in srgb,var(--h) 75%,transparent));box-shadow:inset 0 1px 0 rgba(255,255,255,.55)}
…
const init = (root) => {
  const sec = root.querySelector('.x-ffc'), bg = sec.querySelector('.x-ffc__bg');
  const F = [['9%', '18%', '#3D5BF0', 0], ['86%', '14%', '#CC528A', 1.5], ['13%', '70%', '#E08A1E', 3], ['82%', '66%', '#2E9E5B', 4.5], ['48%', '90%', '#7B61E8', 2], ['94%', '92%', '#2A9BB3', 6]];
  bg.innerHTML = F.map(([x, y, c, d]) => `<span class="x-ffc__f" style="left:${x};top:${y};--h:${c};animation-delay:-${d}s"><svg viewBox="0 0 100 80"><path d="M4 10a7 7 0 0 1 7-7h25l8 8h45a7 7 0 0 1 7 7v54a7 7 0 0 1-7 7H11a7 7 0 0 1-7-7z"/></svg><b></b><i></i></span>`).join('');
  sec.querySelector('.x-ffc__btn').addEventListener('click', (e) => e.preventDefault());
  if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
  const move = (e) => { const r = sec.getBoundingClientRect(); const dx = (e.clientX - r.left) / r.width - .5, dy = (e.clientY - r.top) / r.height - .5;
    bg.style.setProperty('--px', (-dx * 16).toFixed(1) + 'px'); bg.style.setProperty('--py', (-dy * 12).toFixed(1) + 'px'); };
  const reset = () => { bg.style.setProperty('--px', '0px'); bg.style.setProperty('--py', '0px'); };
  sec.addEventListener('pointermove', move); sec.addEventListener('pointerleave', reset);
};
Subscribe to Builder to see the full source.See pricing

Other components from this template

View all

Mac File Window

Disk Cleanup Panel

Glass Folder

File Preview Cards

Shortcut Keycaps

Ticket Pricing

Compare Table

More hero components

View all

Gradient Mesh Hero

More components

View all

AI Prompt Composer

Film Strip Carousel

Auto Tab Showcase

Media Bento Grid

Agent Chat Window

Model Pill Marquee

Director Art Cards

Mac File Window

Keep exploring