Imported library

← Imported library
Free sampleMIT licence

Post carousel

carousel

Carousel from davidjerleke/embla-carousel.

From prompt to live site

  1. 01

    Copy the code

    Grab every file as one text, each carrying its licence notice.

  2. 02

    Paste into your AI

    Drop it into Claude, Cursor or v0 — or straight into your own project.

  3. 03

    Launch it live

    Adapt the copy, wire your data, and ship — with the notice kept alongside.

Read the full code
Post carousel
davidjerleke/embla-carousel@85a5e3cdb697 · 4 code file(s)

Licence notice — required by the licence; keep it with this code:

MIT License

Copyright (c) David Jerleke.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Modifications (CreativePower): converted on 2026-09-30 from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts) into CreativePower's native pattern format — rewritten as plain HTML, CSS and JavaScript on design tokens, with the source's demo imagery, fonts and copy replaced by slots and token-driven defaults.

--- pattern.html ---
<!DOCTYPE html>
<!--
MIT License

Copyright (c) David Jerleke.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Modifications (CreativePower): converted on 2026-09-30 from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts) into CreativePower's native pattern format — rewritten as plain HTML, CSS and JavaScript on design tokens, with the source's demo imagery, fonts and copy replaced by slots and token-driven defaults.
-->
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Post carousel</title>
<style>html,body{margin:0;min-height:100%;background:#07070c}body{-webkit-font-smoothing:antialiased}</style>
<style>/* Post carousel — CreativePower showpiece, converted from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts), by David Jerleke., under the MIT licence. The full licence notice travels with this pattern (its library item's NOTICE.txt). */
[data-sp="post-carousel"]{
  --sp-a: var(--color-primary, #7c5cff);
  --sp-b: var(--color-secondary, #ff5c8a);
  --sp-ground: #07070c;
  --sp-ink: #f4f4f8;
  --sp-dim: color-mix(in oklab, var(--sp-ink) 62%, transparent);
  --sp-line: color-mix(in oklab, var(--sp-ink) 14%, transparent);
  --sp-radius: var(--ds-radius, 14px);
  --sp-radius-lg: var(--ds-radius-lg, 24px);
  --sp-font-display: var(--ds-font-display, "Inter", system-ui, sans-serif);
  --sp-font-body: var(--ds-font-body, "Inter", system-ui, sans-serif);
  --sp-font-mono: var(--ds-font-mono, ui-monospace, "SFMono-Regular", monospace);
  position: relative; isolation: isolate; overflow: hidden;
  min-height: 100vh; width: 100%;
  background: radial-gradient(120% 80% at 50% -10%, color-mix(in oklab, var(--sp-a) 22%, transparent), transparent 60%),
    radial-gradient(90% 70% at 100% 110%, color-mix(in oklab, var(--sp-b) 18%, transparent), transparent 60%), var(--sp-ground);
  color: var(--sp-ink); font-family: var(--sp-font-body);
}
@supports (color: oklch(from red l c h)) {
  [data-sp="post-carousel"]{
    --sp-ground: oklch(from var(--color-on-surface, #0b0b12) min(l, 0.15) min(c, 0.04) h);
    --sp-ink: oklch(from var(--color-surface, #ffffff) max(l, 0.96) min(c, 0.02) h);
  }
}
[data-sp="post-carousel"] *, [data-sp="post-carousel"] *::before, [data-sp="post-carousel"] *::after { box-sizing: border-box; }
[data-sp="post-carousel"] :focus-visible { outline: 2px solid var(--sp-ink); outline-offset: 3px; }
[data-sp="post-carousel"] .sp-art { position: relative; margin: 0; overflow: hidden; background-color: var(--sp-ground); }
[data-sp="post-carousel"] .sp-art > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
[data-sp="post-carousel"] .sp-art::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .22; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"); }
[data-sp="post-carousel"] .sp-art:has(> img)::after { display: none; }
[data-sp="post-carousel"] .sp-art[data-art="1"] { background-image: radial-gradient(120% 90% at 18% 12%, color-mix(in oklab, var(--sp-a) 92%, white 8%), transparent 58%), radial-gradient(90% 80% at 88% 92%, var(--sp-b), transparent 62%), linear-gradient(160deg, color-mix(in oklab, var(--sp-a) 40%, var(--sp-ground)), var(--sp-ground)); }
[data-sp="post-carousel"] .sp-art[data-art="2"] { background-image: conic-gradient(from 210deg at 70% 30%, var(--sp-b), color-mix(in oklab, var(--sp-a) 70%, var(--sp-b)), var(--sp-a), var(--sp-b)); }
[data-sp="post-carousel"] .sp-art[data-art="3"] { background-image: radial-gradient(60% 60% at 50% 40%, color-mix(in oklab, var(--sp-ink) 55%, var(--sp-a)), transparent 62%), linear-gradient(200deg, var(--sp-a), color-mix(in oklab, var(--sp-a) 30%, var(--sp-ground)) 70%); }
[data-sp="post-carousel"] .sp-art[data-art="4"] { background-image: radial-gradient(80% 70% at 30% 80%, var(--sp-b), transparent 60%), radial-gradient(70% 60% at 75% 20%, color-mix(in oklab, var(--sp-b) 40%, var(--sp-ink)), transparent 55%), linear-gradient(20deg, color-mix(in oklab, var(--sp-b) 35%, var(--sp-ground)), var(--sp-ground)); }
[data-sp="post-carousel"] .sp-art[data-art="5"] { background-image: repeating-linear-gradient(115deg, color-mix(in oklab, var(--sp-a) 85%, transparent) 0 14%, color-mix(in oklab, var(--sp-b) 80%, transparent) 14% 26%, transparent 26% 34%), linear-gradient(180deg, color-mix(in oklab, var(--sp-a) 30%, var(--sp-ground)), var(--sp-ground)); }
[data-sp="post-carousel"] .sp-art[data-art="6"] { background-image: radial-gradient(40% 40% at 50% 55%, color-mix(in oklab, var(--sp-b) 85%, white 15%), transparent 70%), radial-gradient(100% 100% at 50% 100%, var(--sp-a), transparent 70%), linear-gradient(0deg, color-mix(in oklab, var(--sp-a) 30%, var(--sp-ground)), var(--sp-ground)); }
[data-sp="post-carousel"] .sp-art[data-art="7"] { background-image: linear-gradient(135deg, var(--sp-a) 0%, color-mix(in oklab, var(--sp-a) 50%, var(--sp-b)) 45%, var(--sp-b) 100%); }
[data-sp="post-carousel"] .sp-art[data-art="8"] { background-image: radial-gradient(90% 60% at 50% 0%, color-mix(in oklab, var(--sp-ink) 35%, var(--sp-b)), transparent 60%), radial-gradient(120% 90% at 0% 100%, var(--sp-a), transparent 60%), linear-gradient(90deg, color-mix(in oklab, var(--sp-b) 40%, var(--sp-ground)), var(--sp-ground)); }
@media (prefers-reduced-motion: reduce) {
  [data-sp="post-carousel"] *, [data-sp="post-carousel"] *::before, [data-sp="post-carousel"] *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}
.pc{position:relative;min-height:100vh;display:grid;align-content:center;padding:7vh clamp(16px,5vw,72px)}
.pc-frame{width:100%;max-width:1240px;margin:0 auto;display:grid;grid-template-columns:1fr auto;grid-template-areas:"head ui" "view view" "dots dots";column-gap:24px;row-gap:clamp(22px,4vh,40px);align-items:end}
.pc-head{grid-area:head}
.pc-eyebrow{font:500 12px/1 var(--sp-font-mono);letter-spacing:.3em;text-transform:uppercase;color:var(--sp-dim);margin:0 0 14px}
.pc-title{font:var(--ds-display-weight,600) clamp(28px,3.8vw,52px)/1.02 var(--sp-font-display);letter-spacing:var(--ds-display-tracking,-.025em);margin:0;max-width:24ch;
  background:linear-gradient(100deg,var(--sp-ink) 40%,color-mix(in oklab,var(--sp-ink) 45%,var(--sp-a)));-webkit-background-clip:text;background-clip:text;color:transparent}
.pc-viewport{grid-area:view;overflow:hidden;cursor:grab;touch-action:pan-y pinch-zoom;outline:none;border-radius:var(--sp-radius-lg);padding:6px;margin:-6px}
.pc-viewport:focus-visible{outline:2px solid var(--sp-ink);outline-offset:2px}
.pc.is-dragging .pc-viewport{cursor:grabbing}
.pc-track{display:flex;will-change:transform;--gap:1rem;--size:100%;margin-left:calc(var(--gap) * -1)}
@media (min-width:600px){.pc-track{--gap:1.6rem;--size:50%}}
@media (min-width:1000px){.pc-track{--gap:2rem;--size:calc(100% / 3)}}
.pc-slide{flex:0 0 var(--size);min-width:0;padding-left:var(--gap)}
.pc-card{height:100%;display:flex;flex-direction:column;border-radius:var(--sp-radius-lg);overflow:hidden;
  background:linear-gradient(180deg,color-mix(in oklab,var(--sp-ink) 7%,transparent),color-mix(in oklab,var(--sp-ink) 3%,transparent));
  box-shadow:inset 0 0 0 1px var(--sp-line),0 30px 60px -40px rgb(0 0 0/.9);transition:transform .35s cubic-bezier(.2,.8,.2,1),box-shadow .35s}
.pc-slide:hover .pc-card{transform:translateY(-4px);box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--sp-ink) 26%,transparent),0 40px 70px -40px rgb(0 0 0/.95)}
.pc-card .sp-art{aspect-ratio:16/10;width:100%}
.pc-body{display:flex;flex-direction:column;gap:10px;padding:clamp(16px,1.8vw,24px);flex:1}
.pc-tag{align-self:flex-start;font:500 11px/1 var(--sp-font-mono);letter-spacing:.18em;text-transform:uppercase;padding:7px 10px;border-radius:99px;
  color:color-mix(in oklab,var(--sp-ink) 80%,var(--sp-a));background:color-mix(in oklab,var(--sp-a) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--sp-a) 34%,transparent)}
.pc-card h3{margin:2px 0 0;font:600 clamp(18px,1.6vw,22px)/1.2 var(--sp-font-display);letter-spacing:-.01em;color:var(--sp-ink)}
.pc-card p{margin:0;font:400 14.5px/1.55 var(--sp-font-body);color:var(--sp-dim)}
.pc-by{margin-top:auto;padding-top:14px;display:flex;align-items:center;gap:10px;border-top:1px solid var(--sp-line);font:500 13px/1.2 var(--sp-font-body);color:var(--sp-ink)}
.pc-by em{font-style:normal;color:var(--sp-dim);margin-left:auto;font:500 12px/1 var(--sp-font-mono);letter-spacing:.06em}
.pc-av{width:30px;height:30px;border-radius:99px;display:grid;place-items:center;font:600 11px/1 var(--sp-font-mono);color:var(--sp-ink);
  background:linear-gradient(135deg,var(--sp-a),var(--sp-b))}
.pc-ui{grid-area:ui;display:flex;gap:10px}
.pc-btn{width:48px;height:48px;border-radius:999px;border:1px solid var(--sp-line);background:color-mix(in oklab,var(--sp-ink) 8%,transparent);
  color:var(--sp-ink);display:grid;place-items:center;cursor:pointer;transition:background .2s,opacity .2s}
.pc-btn:hover:not(:disabled){background:color-mix(in oklab,var(--sp-ink) 18%,transparent)}
.pc-btn:disabled{opacity:.3;cursor:default}
.pc-btn svg{width:18px;height:18px}
.pc-dots{grid-area:dots;display:flex;justify-content:center}
.pc-dot{width:26px;height:24px;border:0;padding:0;background:none;display:grid;place-items:center;cursor:pointer}
.pc-dot::before{content:"";width:8px;height:8px;border-radius:99px;background:color-mix(in oklab,var(--sp-ink) 28%,transparent);transition:width .3s,background .3s}
.pc-dot[aria-current="true"]::before{width:24px;background:linear-gradient(90deg,var(--sp-a),var(--sp-b))}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}</style>
</head><body>
<main class="sp-stage" data-sp="post-carousel">
<section class="pc" aria-roledescription="carousel" aria-label="Latest posts">
  <div class="pc-frame">
    <header class="pc-head">
      <p class="pc-eyebrow" data-slot="eyebrow">The journal</p>
      <h2 class="pc-title" data-slot="title">Notes from the studio floor</h2>
    </header>
    <div class="pc-viewport" tabindex="0" aria-label="Posts — drag or use the arrow keys">
      <div class="pc-track">
        <article class="pc-slide" aria-roledescription="slide" aria-label="1 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="1"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Field guide</span>
              <h3 data-slot="title">Designing for the slow afternoon</h3>
              <p data-slot="body">Why the calmest interfaces are built from fewer, larger decisions made early.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">AL</span><span data-slot="label">Ada Lindqvist</span><em data-slot="label">6 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="2 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="6"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Studio notes</span>
              <h3 data-slot="title">A week without a single meeting</h3>
              <p data-slot="body">What changed when the team swapped standups for a shared, written log.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">TR</span><span data-slot="label">Tomas Reyes</span><em data-slot="label">4 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="3 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="3"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Essay</span>
              <h3 data-slot="title">The case for plain words</h3>
              <p data-slot="body">Short sentences, common nouns and the quiet authority of saying less.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">MO</span><span data-slot="label">Mira Okafor</span><em data-slot="label">8 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="4 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="8"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Process</span>
              <h3 data-slot="title">Sketching in the margins</h3>
              <p data-slot="body">Paper first, pixels second: a small ritual that keeps ideas loose.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">JP</span><span data-slot="label">Jonah Pike</span><em data-slot="label">5 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="5 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="5"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Interview</span>
              <h3 data-slot="title">Building tools that disappear</h3>
              <p data-slot="body">A conversation about software you stop noticing the moment it works.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">LV</span><span data-slot="label">Lena Varga</span><em data-slot="label">11 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="6 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="2"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Field guide</span>
              <h3 data-slot="title">Colour that holds up at night</h3>
              <p data-slot="body">Choosing palettes that stay legible from bright desks to dark rooms.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">SA</span><span data-slot="label">Sam Achebe</span><em data-slot="label">7 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="7 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="7"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Studio notes</span>
              <h3 data-slot="title">Shipping the smallest version</h3>
              <p data-slot="body">How one feature became three weeks shorter by starting with a sentence.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">IN</span><span data-slot="label">Iris Noor</span><em data-slot="label">3 min read</em></div>
            </div>
          </div>
        </article>
      </div>
    </div>
    <div class="pc-ui">
      <button class="pc-btn" type="button" data-dir="-1" aria-label="Previous posts"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 18l-6-6 6-6"/></svg></button>
      <button class="pc-btn" type="button" data-dir="1" aria-label="Next posts"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg></button>
    </div>
    <div class="pc-dots" role="group" aria-label="Choose a page of posts"></div>
  </div>
  <p class="sr-only" aria-live="polite"></p>
</section>
</main>

<script>// Post carousel — CreativePower showpiece, converted from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts), by David Jerleke., under the MIT licence. The full licence notice travels with this pattern (its library item's NOTICE.txt).
(function(){
  var root = document.querySelector('[data-sp="post-carousel"]');
  if (!root) return;
  var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  // Embla's ScrollBody (duration 25, friction 0.68); duration 0 is its instant scroll, used under reduced motion.
  var DURATION = reduced ? 0 : 25, FRICTION = 0.68;
  var wrapEl = root.querySelector('.pc');
  var vp = root.querySelector('.pc-viewport');
  var track = root.querySelector('.pc-track');
  var slides = [].slice.call(root.querySelectorAll('.pc-slide'));
  var prevBtn = root.querySelector('[data-dir="-1"]');
  var nextBtn = root.querySelector('[data-dir="1"]');
  var dotsWrap = root.querySelector('.pc-dots');
  var live = root.querySelector('[aria-live]');
  var n = slides.length, step = 0, perView = 1, maxSnap = 0, index = 0;
  var loc = 0, target = 0, vel = 0, raf = 0, startX = null, startLoc = 0, lastX = 0, dragVel = 0, dots = [];
  
  function clamp(v, a, b) { return Math.min(Math.max(v, a), b); }
  
  // Align 'start' with trimmed snaps: one snap per slide until the last full view.
  function measure() {
    step = slides[0].getBoundingClientRect().width;
    perView = Math.max(1, Math.round(vp.clientWidth / step));
    maxSnap = Math.max(0, n - perView);
    if (dots.length !== maxSnap + 1) {
      dotsWrap.innerHTML = '';
      for (var i = 0; i <= maxSnap; i++) {
        (function (k) {
          var b = document.createElement('button');
          b.type = 'button'; b.className = 'pc-dot'; b.setAttribute('aria-label', 'Go to post ' + (k + 1));
          b.addEventListener('click', function () { goTo(k); });
          dotsWrap.appendChild(b);
        })(i);
      }
      dots = [].slice.call(dotsWrap.children);
    }
    index = clamp(index, 0, maxSnap);
    target = loc = index;
  }
  
  function render() {
    track.style.transform = 'translate3d(' + (-loc * step).toFixed(2) + 'px,0,0)';
  }
  function seek() {
    if (!DURATION) { loc = target; vel = 0; return; }
    vel += (target - loc) / DURATION;
    vel *= FRICTION;
    loc += vel;
  }
  function tick() {
    seek();
    if (Math.abs(target - loc) < 0.001 && Math.abs(vel) < 0.001) { loc = target; vel = 0; raf = 0; render(); return; }
    render();
    raf = requestAnimationFrame(tick);
  }
  function run() {
    if (!DURATION) { loc = target; render(); return; }
    if (!raf) raf = requestAnimationFrame(tick);
  }
  function update() {
    prevBtn.disabled = index <= 0;
    nextBtn.disabled = index >= maxSnap;
    dots.forEach(function (d, k) { d.setAttribute('aria-current', k === index ? 'true' : 'false'); });
    slides.forEach(function (s, k) { s.setAttribute('aria-hidden', k >= index && k < index + perView ? 'false' : 'true'); });
    var last = Math.min(n, index + perView);
    live.textContent = 'Showing posts ' + (index + 1) + (last > index + 1 ? ' to ' + last : '') + ' of ' + n;
  }
  function goTo(k) { index = clamp(k, 0, maxSnap); target = index; update(); run(); }
  
  prevBtn.addEventListener('click', function () { goTo(index - 1); });
  nextBtn.addEventListener('click', function () { goTo(index + 1); });
  vp.addEventListener('keydown', function (e) {
    if (e.key === 'ArrowRight') { goTo(index + 1); e.preventDefault(); }
    else if (e.key === 'ArrowLeft') { goTo(index - 1); e.preventDefault(); }
    else if (e.key === 'Home') { goTo(0); e.preventDefault(); }
    else if (e.key === 'End') { goTo(maxSnap); e.preventDefault(); }
  });
  vp.addEventListener('pointerdown', function (e) {
    if (e.button !== 0) return;
    startX = lastX = e.clientX; startLoc = loc; dragVel = 0; vel = 0;
    wrapEl.classList.add('is-dragging'); vp.setPointerCapture(e.pointerId);
  });
  vp.addEventListener('pointermove', function (e) {
    if (startX === null) return;
    dragVel = (e.clientX - lastX) / step; lastX = e.clientX;
    var raw = startLoc - (e.clientX - startX) / step;
    // Edge resistance past the first and last snap, as Embla's drag gives.
    if (raw < 0) raw = raw * 0.3; else if (raw > maxSnap) raw = maxSnap + (raw - maxSnap) * 0.3;
    loc = target = raw;
    render();
  });
  function endDrag() {
    if (startX === null) return;
    startX = null; wrapEl.classList.remove('is-dragging');
    goTo(Math.round(loc - dragVel * 5));
  }
  vp.addEventListener('pointerup', endDrag);
  vp.addEventListener('pointercancel', endDrag);
  window.addEventListener('resize', function () { measure(); render(); update(); });
  measure();
  render();
  update();
})();</script>
</body></html>

--- pattern.css ---
/*!
MIT License

Copyright (c) David Jerleke.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Modifications (CreativePower): converted on 2026-09-30 from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts) into CreativePower's native pattern format — rewritten as plain HTML, CSS and JavaScript on design tokens, with the source's demo imagery, fonts and copy replaced by slots and token-driven defaults.
*/
/* Post carousel — CreativePower showpiece, converted from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts), by David Jerleke., under the MIT licence. The full licence notice travels with this pattern (its library item's NOTICE.txt). */
[data-sp="post-carousel"]{
  --sp-a: var(--color-primary, #7c5cff);
  --sp-b: var(--color-secondary, #ff5c8a);
  --sp-ground: #07070c;
  --sp-ink: #f4f4f8;
  --sp-dim: color-mix(in oklab, var(--sp-ink) 62%, transparent);
  --sp-line: color-mix(in oklab, var(--sp-ink) 14%, transparent);
  --sp-radius: var(--ds-radius, 14px);
  --sp-radius-lg: var(--ds-radius-lg, 24px);
  --sp-font-display: var(--ds-font-display, "Inter", system-ui, sans-serif);
  --sp-font-body: var(--ds-font-body, "Inter", system-ui, sans-serif);
  --sp-font-mono: var(--ds-font-mono, ui-monospace, "SFMono-Regular", monospace);
  position: relative; isolation: isolate; overflow: hidden;
  min-height: 100vh; width: 100%;
  background: radial-gradient(120% 80% at 50% -10%, color-mix(in oklab, var(--sp-a) 22%, transparent), transparent 60%),
    radial-gradient(90% 70% at 100% 110%, color-mix(in oklab, var(--sp-b) 18%, transparent), transparent 60%), var(--sp-ground);
  color: var(--sp-ink); font-family: var(--sp-font-body);
}
@supports (color: oklch(from red l c h)) {
  [data-sp="post-carousel"]{
    --sp-ground: oklch(from var(--color-on-surface, #0b0b12) min(l, 0.15) min(c, 0.04) h);
    --sp-ink: oklch(from var(--color-surface, #ffffff) max(l, 0.96) min(c, 0.02) h);
  }
}
[data-sp="post-carousel"] *, [data-sp="post-carousel"] *::before, [data-sp="post-carousel"] *::after { box-sizing: border-box; }
[data-sp="post-carousel"] :focus-visible { outline: 2px solid var(--sp-ink); outline-offset: 3px; }
[data-sp="post-carousel"] .sp-art { position: relative; margin: 0; overflow: hidden; background-color: var(--sp-ground); }
[data-sp="post-carousel"] .sp-art > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
[data-sp="post-carousel"] .sp-art::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .22; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"); }
[data-sp="post-carousel"] .sp-art:has(> img)::after { display: none; }
[data-sp="post-carousel"] .sp-art[data-art="1"] { background-image: radial-gradient(120% 90% at 18% 12%, color-mix(in oklab, var(--sp-a) 92%, white 8%), transparent 58%), radial-gradient(90% 80% at 88% 92%, var(--sp-b), transparent 62%), linear-gradient(160deg, color-mix(in oklab, var(--sp-a) 40%, var(--sp-ground)), var(--sp-ground)); }
[data-sp="post-carousel"] .sp-art[data-art="2"] { background-image: conic-gradient(from 210deg at 70% 30%, var(--sp-b), color-mix(in oklab, var(--sp-a) 70%, var(--sp-b)), var(--sp-a), var(--sp-b)); }
[data-sp="post-carousel"] .sp-art[data-art="3"] { background-image: radial-gradient(60% 60% at 50% 40%, color-mix(in oklab, var(--sp-ink) 55%, var(--sp-a)), transparent 62%), linear-gradient(200deg, var(--sp-a), color-mix(in oklab, var(--sp-a) 30%, var(--sp-ground)) 70%); }
[data-sp="post-carousel"] .sp-art[data-art="4"] { background-image: radial-gradient(80% 70% at 30% 80%, var(--sp-b), transparent 60%), radial-gradient(70% 60% at 75% 20%, color-mix(in oklab, var(--sp-b) 40%, var(--sp-ink)), transparent 55%), linear-gradient(20deg, color-mix(in oklab, var(--sp-b) 35%, var(--sp-ground)), var(--sp-ground)); }
[data-sp="post-carousel"] .sp-art[data-art="5"] { background-image: repeating-linear-gradient(115deg, color-mix(in oklab, var(--sp-a) 85%, transparent) 0 14%, color-mix(in oklab, var(--sp-b) 80%, transparent) 14% 26%, transparent 26% 34%), linear-gradient(180deg, color-mix(in oklab, var(--sp-a) 30%, var(--sp-ground)), var(--sp-ground)); }
[data-sp="post-carousel"] .sp-art[data-art="6"] { background-image: radial-gradient(40% 40% at 50% 55%, color-mix(in oklab, var(--sp-b) 85%, white 15%), transparent 70%), radial-gradient(100% 100% at 50% 100%, var(--sp-a), transparent 70%), linear-gradient(0deg, color-mix(in oklab, var(--sp-a) 30%, var(--sp-ground)), var(--sp-ground)); }
[data-sp="post-carousel"] .sp-art[data-art="7"] { background-image: linear-gradient(135deg, var(--sp-a) 0%, color-mix(in oklab, var(--sp-a) 50%, var(--sp-b)) 45%, var(--sp-b) 100%); }
[data-sp="post-carousel"] .sp-art[data-art="8"] { background-image: radial-gradient(90% 60% at 50% 0%, color-mix(in oklab, var(--sp-ink) 35%, var(--sp-b)), transparent 60%), radial-gradient(120% 90% at 0% 100%, var(--sp-a), transparent 60%), linear-gradient(90deg, color-mix(in oklab, var(--sp-b) 40%, var(--sp-ground)), var(--sp-ground)); }
@media (prefers-reduced-motion: reduce) {
  [data-sp="post-carousel"] *, [data-sp="post-carousel"] *::before, [data-sp="post-carousel"] *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}
.pc{position:relative;min-height:100vh;display:grid;align-content:center;padding:7vh clamp(16px,5vw,72px)}
.pc-frame{width:100%;max-width:1240px;margin:0 auto;display:grid;grid-template-columns:1fr auto;grid-template-areas:"head ui" "view view" "dots dots";column-gap:24px;row-gap:clamp(22px,4vh,40px);align-items:end}
.pc-head{grid-area:head}
.pc-eyebrow{font:500 12px/1 var(--sp-font-mono);letter-spacing:.3em;text-transform:uppercase;color:var(--sp-dim);margin:0 0 14px}
.pc-title{font:var(--ds-display-weight,600) clamp(28px,3.8vw,52px)/1.02 var(--sp-font-display);letter-spacing:var(--ds-display-tracking,-.025em);margin:0;max-width:24ch;
  background:linear-gradient(100deg,var(--sp-ink) 40%,color-mix(in oklab,var(--sp-ink) 45%,var(--sp-a)));-webkit-background-clip:text;background-clip:text;color:transparent}
.pc-viewport{grid-area:view;overflow:hidden;cursor:grab;touch-action:pan-y pinch-zoom;outline:none;border-radius:var(--sp-radius-lg);padding:6px;margin:-6px}
.pc-viewport:focus-visible{outline:2px solid var(--sp-ink);outline-offset:2px}
.pc.is-dragging .pc-viewport{cursor:grabbing}
.pc-track{display:flex;will-change:transform;--gap:1rem;--size:100%;margin-left:calc(var(--gap) * -1)}
@media (min-width:600px){.pc-track{--gap:1.6rem;--size:50%}}
@media (min-width:1000px){.pc-track{--gap:2rem;--size:calc(100% / 3)}}
.pc-slide{flex:0 0 var(--size);min-width:0;padding-left:var(--gap)}
.pc-card{height:100%;display:flex;flex-direction:column;border-radius:var(--sp-radius-lg);overflow:hidden;
  background:linear-gradient(180deg,color-mix(in oklab,var(--sp-ink) 7%,transparent),color-mix(in oklab,var(--sp-ink) 3%,transparent));
  box-shadow:inset 0 0 0 1px var(--sp-line),0 30px 60px -40px rgb(0 0 0/.9);transition:transform .35s cubic-bezier(.2,.8,.2,1),box-shadow .35s}
.pc-slide:hover .pc-card{transform:translateY(-4px);box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--sp-ink) 26%,transparent),0 40px 70px -40px rgb(0 0 0/.95)}
.pc-card .sp-art{aspect-ratio:16/10;width:100%}
.pc-body{display:flex;flex-direction:column;gap:10px;padding:clamp(16px,1.8vw,24px);flex:1}
.pc-tag{align-self:flex-start;font:500 11px/1 var(--sp-font-mono);letter-spacing:.18em;text-transform:uppercase;padding:7px 10px;border-radius:99px;
  color:color-mix(in oklab,var(--sp-ink) 80%,var(--sp-a));background:color-mix(in oklab,var(--sp-a) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--sp-a) 34%,transparent)}
.pc-card h3{margin:2px 0 0;font:600 clamp(18px,1.6vw,22px)/1.2 var(--sp-font-display);letter-spacing:-.01em;color:var(--sp-ink)}
.pc-card p{margin:0;font:400 14.5px/1.55 var(--sp-font-body);color:var(--sp-dim)}
.pc-by{margin-top:auto;padding-top:14px;display:flex;align-items:center;gap:10px;border-top:1px solid var(--sp-line);font:500 13px/1.2 var(--sp-font-body);color:var(--sp-ink)}
.pc-by em{font-style:normal;color:var(--sp-dim);margin-left:auto;font:500 12px/1 var(--sp-font-mono);letter-spacing:.06em}
.pc-av{width:30px;height:30px;border-radius:99px;display:grid;place-items:center;font:600 11px/1 var(--sp-font-mono);color:var(--sp-ink);
  background:linear-gradient(135deg,var(--sp-a),var(--sp-b))}
.pc-ui{grid-area:ui;display:flex;gap:10px}
.pc-btn{width:48px;height:48px;border-radius:999px;border:1px solid var(--sp-line);background:color-mix(in oklab,var(--sp-ink) 8%,transparent);
  color:var(--sp-ink);display:grid;place-items:center;cursor:pointer;transition:background .2s,opacity .2s}
.pc-btn:hover:not(:disabled){background:color-mix(in oklab,var(--sp-ink) 18%,transparent)}
.pc-btn:disabled{opacity:.3;cursor:default}
.pc-btn svg{width:18px;height:18px}
.pc-dots{grid-area:dots;display:flex;justify-content:center}
.pc-dot{width:26px;height:24px;border:0;padding:0;background:none;display:grid;place-items:center;cursor:pointer}
.pc-dot::before{content:"";width:8px;height:8px;border-radius:99px;background:color-mix(in oklab,var(--sp-ink) 28%,transparent);transition:width .3s,background .3s}
.pc-dot[aria-current="true"]::before{width:24px;background:linear-gradient(90deg,var(--sp-a),var(--sp-b))}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

--- pattern.js ---
/*!
MIT License

Copyright (c) David Jerleke.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Modifications (CreativePower): converted on 2026-09-30 from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts) into CreativePower's native pattern format — rewritten as plain HTML, CSS and JavaScript on design tokens, with the source's demo imagery, fonts and copy replaced by slots and token-driven defaults.
*/
// Post carousel — CreativePower showpiece, converted from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts), by David Jerleke., under the MIT licence. The full licence notice travels with this pattern (its library item's NOTICE.txt).
(function(){
  var root = document.querySelector('[data-sp="post-carousel"]');
  if (!root) return;
  var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  // Embla's ScrollBody (duration 25, friction 0.68); duration 0 is its instant scroll, used under reduced motion.
  var DURATION = reduced ? 0 : 25, FRICTION = 0.68;
  var wrapEl = root.querySelector('.pc');
  var vp = root.querySelector('.pc-viewport');
  var track = root.querySelector('.pc-track');
  var slides = [].slice.call(root.querySelectorAll('.pc-slide'));
  var prevBtn = root.querySelector('[data-dir="-1"]');
  var nextBtn = root.querySelector('[data-dir="1"]');
  var dotsWrap = root.querySelector('.pc-dots');
  var live = root.querySelector('[aria-live]');
  var n = slides.length, step = 0, perView = 1, maxSnap = 0, index = 0;
  var loc = 0, target = 0, vel = 0, raf = 0, startX = null, startLoc = 0, lastX = 0, dragVel = 0, dots = [];
  
  function clamp(v, a, b) { return Math.min(Math.max(v, a), b); }
  
  // Align 'start' with trimmed snaps: one snap per slide until the last full view.
  function measure() {
    step = slides[0].getBoundingClientRect().width;
    perView = Math.max(1, Math.round(vp.clientWidth / step));
    maxSnap = Math.max(0, n - perView);
    if (dots.length !== maxSnap + 1) {
      dotsWrap.innerHTML = '';
      for (var i = 0; i <= maxSnap; i++) {
        (function (k) {
          var b = document.createElement('button');
          b.type = 'button'; b.className = 'pc-dot'; b.setAttribute('aria-label', 'Go to post ' + (k + 1));
          b.addEventListener('click', function () { goTo(k); });
          dotsWrap.appendChild(b);
        })(i);
      }
      dots = [].slice.call(dotsWrap.children);
    }
    index = clamp(index, 0, maxSnap);
    target = loc = index;
  }
  
  function render() {
    track.style.transform = 'translate3d(' + (-loc * step).toFixed(2) + 'px,0,0)';
  }
  function seek() {
    if (!DURATION) { loc = target; vel = 0; return; }
    vel += (target - loc) / DURATION;
    vel *= FRICTION;
    loc += vel;
  }
  function tick() {
    seek();
    if (Math.abs(target - loc) < 0.001 && Math.abs(vel) < 0.001) { loc = target; vel = 0; raf = 0; render(); return; }
    render();
    raf = requestAnimationFrame(tick);
  }
  function run() {
    if (!DURATION) { loc = target; render(); return; }
    if (!raf) raf = requestAnimationFrame(tick);
  }
  function update() {
    prevBtn.disabled = index <= 0;
    nextBtn.disabled = index >= maxSnap;
    dots.forEach(function (d, k) { d.setAttribute('aria-current', k === index ? 'true' : 'false'); });
    slides.forEach(function (s, k) { s.setAttribute('aria-hidden', k >= index && k < index + perView ? 'false' : 'true'); });
    var last = Math.min(n, index + perView);
    live.textContent = 'Showing posts ' + (index + 1) + (last > index + 1 ? ' to ' + last : '') + ' of ' + n;
  }
  function goTo(k) { index = clamp(k, 0, maxSnap); target = index; update(); run(); }
  
  prevBtn.addEventListener('click', function () { goTo(index - 1); });
  nextBtn.addEventListener('click', function () { goTo(index + 1); });
  vp.addEventListener('keydown', function (e) {
    if (e.key === 'ArrowRight') { goTo(index + 1); e.preventDefault(); }
    else if (e.key === 'ArrowLeft') { goTo(index - 1); e.preventDefault(); }
    else if (e.key === 'Home') { goTo(0); e.preventDefault(); }
    else if (e.key === 'End') { goTo(maxSnap); e.preventDefault(); }
  });
  vp.addEventListener('pointerdown', function (e) {
    if (e.button !== 0) return;
    startX = lastX = e.clientX; startLoc = loc; dragVel = 0; vel = 0;
    wrapEl.classList.add('is-dragging'); vp.setPointerCapture(e.pointerId);
  });
  vp.addEventListener('pointermove', function (e) {
    if (startX === null) return;
    dragVel = (e.clientX - lastX) / step; lastX = e.clientX;
    var raw = startLoc - (e.clientX - startX) / step;
    // Edge resistance past the first and last snap, as Embla's drag gives.
    if (raw < 0) raw = raw * 0.3; else if (raw > maxSnap) raw = maxSnap + (raw - maxSnap) * 0.3;
    loc = target = raw;
    render();
  });
  function endDrag() {
    if (startX === null) return;
    startX = null; wrapEl.classList.remove('is-dragging');
    goTo(Math.round(loc - dragVel * 5));
  }
  vp.addEventListener('pointerup', endDrag);
  vp.addEventListener('pointercancel', endDrag);
  window.addEventListener('resize', function () { measure(); render(); update(); });
  measure();
  render();
  update();
})();

--- markup.html ---
<!--
MIT License

Copyright (c) David Jerleke.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Modifications (CreativePower): converted on 2026-09-30 from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts) into CreativePower's native pattern format — rewritten as plain HTML, CSS and JavaScript on design tokens, with the source's demo imagery, fonts and copy replaced by slots and token-driven defaults.
-->
<main class="sp-stage" data-sp="post-carousel">
<section class="pc" aria-roledescription="carousel" aria-label="Latest posts">
  <div class="pc-frame">
    <header class="pc-head">
      <p class="pc-eyebrow" data-slot="eyebrow">The journal</p>
      <h2 class="pc-title" data-slot="title">Notes from the studio floor</h2>
    </header>
    <div class="pc-viewport" tabindex="0" aria-label="Posts — drag or use the arrow keys">
      <div class="pc-track">
        <article class="pc-slide" aria-roledescription="slide" aria-label="1 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="1"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Field guide</span>
              <h3 data-slot="title">Designing for the slow afternoon</h3>
              <p data-slot="body">Why the calmest interfaces are built from fewer, larger decisions made early.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">AL</span><span data-slot="label">Ada Lindqvist</span><em data-slot="label">6 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="2 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="6"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Studio notes</span>
              <h3 data-slot="title">A week without a single meeting</h3>
              <p data-slot="body">What changed when the team swapped standups for a shared, written log.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">TR</span><span data-slot="label">Tomas Reyes</span><em data-slot="label">4 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="3 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="3"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Essay</span>
              <h3 data-slot="title">The case for plain words</h3>
              <p data-slot="body">Short sentences, common nouns and the quiet authority of saying less.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">MO</span><span data-slot="label">Mira Okafor</span><em data-slot="label">8 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="4 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="8"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Process</span>
              <h3 data-slot="title">Sketching in the margins</h3>
              <p data-slot="body">Paper first, pixels second: a small ritual that keeps ideas loose.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">JP</span><span data-slot="label">Jonah Pike</span><em data-slot="label">5 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="5 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="5"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Interview</span>
              <h3 data-slot="title">Building tools that disappear</h3>
              <p data-slot="body">A conversation about software you stop noticing the moment it works.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">LV</span><span data-slot="label">Lena Varga</span><em data-slot="label">11 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="6 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="2"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Field guide</span>
              <h3 data-slot="title">Colour that holds up at night</h3>
              <p data-slot="body">Choosing palettes that stay legible from bright desks to dark rooms.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">SA</span><span data-slot="label">Sam Achebe</span><em data-slot="label">7 min read</em></div>
            </div>
          </div>
        </article>
        <article class="pc-slide" aria-roledescription="slide" aria-label="7 of 7">
          <div class="pc-card">
            <figure class="sp-art" data-slot="image" data-art="7"></figure>
            <div class="pc-body">
              <span class="pc-tag" data-slot="eyebrow">Studio notes</span>
              <h3 data-slot="title">Shipping the smallest version</h3>
              <p data-slot="body">How one feature became three weeks shorter by starting with a sentence.</p>
              <div class="pc-by"><span class="pc-av" aria-hidden="true">IN</span><span data-slot="label">Iris Noor</span><em data-slot="label">3 min read</em></div>
            </div>
          </div>
        </article>
      </div>
    </div>
    <div class="pc-ui">
      <button class="pc-btn" type="button" data-dir="-1" aria-label="Previous posts"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 18l-6-6 6-6"/></svg></button>
      <button class="pc-btn" type="button" data-dir="1" aria-label="Next posts"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg></button>
    </div>
    <div class="pc-dots" role="group" aria-label="Choose a page of posts"></div>
  </div>
  <p class="sr-only" aria-live="polite"></p>
</section>
</main>
Source and licence

Source: davidjerleke/embla-carousel@85a5e3cdb697

Author: David Jerleke.

Entry: website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts

  • Converted into the native showpiece "post-carousel" (lib/motion-patterns/showpiece/post-carousel.ts): plain HTML/CSS/JS on the design tokens, with slots for imagery and text. The shipped files are the conversion; the source files it was converted from (source.paths, at source.commit) are not shipped.
  • Passed step 7 on 2026-09-30: render, reduced, keyboard, noTrap, tokens, slots, notice, engines (scripts/ui-blocks/check-showpiece.ts).
MIT License

Copyright (c) David Jerleke.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Modifications (CreativePower): converted on 2026-09-30 from davidjerleke/embla-carousel@85a5e3cdb697 (website/src/content/v9/examples/Predefined/Basic/SlidesPerView.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselArrowButtons.ts, website/src/content/v9/sandboxes/Vanilla/SandboxFilesSrc/EmblaCarouselDotButton.ts, packages/embla-carousel/src/components/ScrollBody.ts) into CreativePower's native pattern format — rewritten as plain HTML, CSS and JavaScript on design tokens, with the source's demo imagery, fonts and copy replaced by slots and token-driven defaults.
Files (4)
  • pattern.html (20,928 bytes)
  • pattern.css (9,611 bytes)
  • pattern.js (5,018 bytes)
  • markup.html (5,968 bytes)

Want the whole library?

Every item's prompt, code and instructions, with a CreativePower subscription.

See plans

More carousel templates