Cheque
React + Tailwind
// A fine wave repeated across the paper, the anti-forgery pattern banks print.
const GUILLOCHE = Array.from({ length: 5 }, (_, k) => {
let d = `M0 ${16 + k * 2}`;
for (let x = 0; x <= 200; x += 5) d += ` L${x} ${(16 + k * 2 + Math.sin((x + k * 9) / 6.5) * (7 - k)).toFixed(1)}`;
return d;
});
const SIGNATURE = 'M4 30C10 12 15 4 17 8C19 14 13 30 16 31C20 28 24 14 28 12C31 12 27 28 30 29C34 28 36 20 40 19C43 20 39 28 43 28C47 27 50 17 53 8C55 3 57 6 55 14C53 22 52 28 55 28C59 27 62 20 64 21C66 24 64 29 67 28C72 26 74 18 80 10C76 22 76 30 80 29C84 26 88 22 94 22C104 22 112 20 124 15';
const css = `
.cb-cheque { --paper: light-dark(#f3f4f7, #e5e6e9); --print: light-dark(#373a40, #121417); --soft: color-mix(in oklab, var(--print) 74%, var(--paper)); --flag: light-dark(#373a40, #232529); --flag-ink: light-dark(#fbfcfd, #f1f2f3); --hole: light-dark(#6d7179, #121417); flex: none; position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; color: light-dark(#42454c, #e5e6e9); font-size: 14px; font-weight: 500; cursor: pointer; -webkit-user-select: none; user-select: none; }
.cb-cheque__input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; }
.cb-cheque__art { position: relative; display: block; width: 268px; height: 152px; filter: drop-shadow(0 6px 8px rgba(0, 0, 0, 0.34)); transform: rotate(-1.4deg); }
.cb-cheque__input:focus-visible + .cb-cheque__art { outline: 2px solid light-dark(#5f626a, #a7abb2); outline-offset: 3px; border-radius: 6px; }
.cb-cheque__sheet { position: absolute; inset: 0; overflow: hidden; border-radius: 3px; background: var(--paper); color: var(--print); font-family: Georgia, 'Times New Roman', serif; }
.cb-cheque__wave { position: absolute; right: 0; top: 0; width: 212px; height: 100%; opacity: 0.2; fill: none; stroke: var(--print); stroke-width: 0.55; }
/* The tear-off stub, split from the cheque by a row of real holes. */
.cb-cheque__holes { position: absolute; left: 50px; top: 0; bottom: 0; width: 4px; background: radial-gradient(circle at 2px 3px, var(--hole) 1.3px, transparent 1.6px) 0 0 / 4px 6px; }
.cb-cheque__stub { position: absolute; left: 6px; top: 8px; width: 40px; font-size: 6.5px; line-height: 1.5; }
.cb-cheque__stub b { display: block; font-size: 10px; }
.cb-cheque__bank { position: absolute; left: 62px; top: 8px; font-size: 11.5px; font-weight: 700; letter-spacing: -0.01em; }
.cb-cheque__num { position: absolute; right: 8px; top: 9px; font: 700 8.5px 'Courier New', Courier, monospace; }
.cb-cheque__row { position: absolute; left: 62px; right: 8px; display: flex; align-items: flex-end; gap: 5px; font-size: 6.5px; letter-spacing: 0.02em; text-transform: uppercase; }
.cb-cheque__row i { flex: 1; min-width: 0; padding: 0 3px 1px; border-bottom: 1px solid var(--print); font: italic 700 11px/1.1 Georgia, 'Times New Roman', serif; letter-spacing: 0; text-transform: none; white-space: nowrap; overflow: hidden; }
.cb-cheque__amount { position: absolute; right: 8px; top: 26px; padding: 2px 5px; border: 1px solid var(--print); background: var(--paper); font: 700 11px 'Courier New', Courier, monospace; }
.cb-cheque__line { position: absolute; left: 150px; right: 10px; top: 110px; height: 1px; background: var(--print); }
.cb-cheque__sign-label { position: absolute; right: 10px; top: 112px; font-size: 6px; letter-spacing: 0.04em; text-transform: uppercase; }
.cb-cheque__micr { position: absolute; left: 62px; bottom: 7px; font: 700 8.5px 'Courier New', Courier, monospace; letter-spacing: 0.08em; }
.cb-cheque__pen { position: absolute; left: 134px; top: 82px; width: 130px; height: 36px; overflow: visible; fill: none; stroke: var(--print); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.cb-cheque__ink { stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0; transition: opacity 0.28s, stroke-dashoffset 0s 0.28s; }
.cb-cheque__input:checked + .cb-cheque__art .cb-cheque__ink { stroke-dashoffset: 0; opacity: 1; transition: stroke-dashoffset 0.85s cubic-bezier(0.35, 0.1, 0.6, 1) 0.18s, opacity 0s; }
.cb-cheque__flag { position: absolute; left: 86px; top: 100px; display: flex; align-items: center; height: 19px; padding: 0 13px 0 8px; background: var(--flag); color: var(--flag-ink); clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%); font: 700 9.5px system-ui, sans-serif; white-space: nowrap; transform-origin: 0 50%; transition: transform 0.3s cubic-bezier(0.3, 1.5, 0.5, 1), opacity 0.2s; }
.cb-cheque:hover .cb-cheque__flag { transform: translateX(4px); }
.cb-cheque__input:checked + .cb-cheque__art .cb-cheque__flag { transform: translate(-28px, 34px) rotate(-30deg) scale(0.9); opacity: 0; transition: transform 0.36s ease-in, opacity 0.2s 0.14s; }
.cb-cheque__stamp { position: absolute; left: 68px; top: 88px; padding: 3px 9px; border: 2.5px solid var(--print); border-radius: 4px; color: var(--print); font: 900 18px/1 'Arial Black', Impact, system-ui, sans-serif; letter-spacing: 0.08em; opacity: 0; transform: rotate(-11deg) scale(1.9); transition: opacity 0.12s, transform 0.12s; }
.cb-cheque__input:checked + .cb-cheque__art .cb-cheque__stamp { opacity: 0.78; transform: rotate(-11deg); transition: opacity 0.06s 1.02s, transform 0.16s cubic-bezier(0.5, 0, 1, 0.6) 1.02s; }
.cb-cheque__input:checked + .cb-cheque__art { animation: cb-cheque-thud 0.3s cubic-bezier(0.3, 1.6, 0.5, 1) 1.17s; }
@keyframes cb-cheque-thud {
0% { transform: rotate(-1.4deg) translateY(3px) scale(0.99); }
100% { transform: rotate(-1.4deg); }
}
@media (prefers-reduced-motion: reduce) {
.cb-cheque *, .cb-cheque__input:checked + .cb-cheque__art, .cb-cheque__input:checked + .cb-cheque__art * { animation: none !important; transition: none !important; }
}
`;
export function ChequeCheckbox() {
return (
<>
<style>
{css}
</style>
<label className="cb-cheque">
<input className="cb-cheque__input" type="checkbox" />
<span className="cb-cheque__art" aria-hidden="true">
<span className="cb-cheque__sheet">
<svg className="cb-cheque__wave" viewBox="0 0 212 152" preserveAspectRatio="none">
{[0, 34, 68, 102].map((y) => (
<g key={y} transform={`translate(0 ${y})`}>
{GUILLOCHE.map((d, i) => (
<path key={i} d={d} />
))}
</g>
))}
</svg>
<span className="cb-cheque__stub">
<b>No. 481</b>
To M. Holt
<br />
Invoice 22
<br />
$1,200.00
</span>
<span className="cb-cheque__holes" />
<span className="cb-cheque__bank">First Motion Bank</span>
<span className="cb-cheque__num">No. 481</span>
<span className="cb-cheque__amount">$1,200.00</span>
<span className="cb-cheque__row" style={{ top: 46, right: 8 }}>
Pay <i>Mira Holt</i>
</span>
<span className="cb-cheque__row" style={{ top: 66 }}>
<i>One thousand two hundred only</i>
</span>
<span className="cb-cheque__line" />
<span className="cb-cheque__sign-label">Authorised signature</span>
<span className="cb-cheque__micr">⑆021000⑆ 8841 0327⑈ 481</span>
<svg className="cb-cheque__pen" viewBox="0 0 130 36">
<path className="cb-cheque__ink" pathLength={1} d={SIGNATURE} />
</svg>
<span className="cb-cheque__stamp">PAID</span>
</span>
<span className="cb-cheque__flag">Sign here</span>
</span>
Sign and pay
</label>
</>
);
}Markup where the component goes, CSS in your stylesheet. No JavaScript.
HTML
<label class="cb-cheque">
<input class="cb-cheque__input" type="checkbox"/>
<span class="cb-cheque__art" aria-hidden="true">
<span class="cb-cheque__sheet">
<svg class="cb-cheque__wave" viewBox="0 0 212 152" preserveAspectRatio="none">
<g transform="translate(0 0)">
<path d="M0 16 L0 16.0 L5 20.9 L10 23.0 L15 21.2 L20 16.5 L25 11.5 L30 9.0 L35 10.5 L40 15.1 L45 20.2 L50 22.9 L55 21.7 L60 17.3 L65 12.2 L70 9.2 L75 10.0 L80 14.2 L85 19.4 L90 22.7 L95 22.2 L100 18.2 L105 13.0 L110 9.4 L115 9.6 L120 13.4 L125 18.6 L130 22.4 L135 22.6 L140 19.1 L145 13.8 L150 9.8 L155 9.3 L160 12.5 L165 17.7 L170 22.0 L175 22.8 L180 19.8 L185 14.7 L190 10.3 L195 9.1 L200 11.8"></path>
<path d="M0 18 L0 23.9 L5 23.0 L10 19.3 L15 14.9 L20 12.2 L25 12.8 L30 16.3 L35 20.8 L40 23.7 L45 23.4 L50 20.0 L55 15.5 L60 12.4 L65 12.4 L70 15.6 L75 20.1 L80 23.4 L85 23.7 L90 20.8 L95 16.3 L100 12.8 L105 12.2 L110 14.9 L115 19.4 L120 23.0 L125 23.9 L130 21.4 L135 17.0 L140 13.2 L145 12.1 L150 14.3 L155 18.6 L160 22.6 L165 24.0 L170 22.0 L175 17.8 L180 13.7 L185 12.0 L190 13.7 L195 17.8 L200 22.0"></path>
<path d="M0 20 L0 21.8 L5 18.1 L10 15.4 L15 15.3 L20 17.9 L25 21.6 L30 24.5 L35 24.8 L40 22.4 L45 18.7 L50 15.7 L55 15.1 L60 17.3 L65 21.0 L70 24.1 L75 24.9 L80 22.9 L85 19.3 L90 16.1 L95 15.0 L100 16.8 L105 20.4 L110 23.7 L115 25.0 L120 23.4 L125 20.0 L130 16.5 L135 15.0 L140 16.3 L145 19.7 L150 23.3 L155 25.0 L160 23.9 L165 20.6 L170 17.0 L175 15.1 L180 15.9 L185 19.1 L190 22.8 L195 24.9 L200 24.3"></path>
<path d="M0 22 L0 18.6 L5 18.1 L10 19.8 L15 22.7 L20 25.2 L25 26.0 L30 24.4 L35 21.5 L40 18.9 L45 18.0 L50 19.4 L55 22.2 L60 24.9 L65 26.0 L70 24.8 L75 22.1 L80 19.3 L85 18.0 L90 19.0 L95 21.7 L100 24.5 L105 26.0 L110 25.2 L115 22.6 L120 19.7 L125 18.1 L130 18.7 L135 21.2 L140 24.1 L145 25.9 L150 25.5 L155 23.1 L160 20.1 L165 18.2 L170 18.4 L175 20.7 L180 23.7 L185 25.7 L190 25.7 L195 23.6 L200 20.6"></path>
<path d="M0 24 L0 22.0 L5 24.1 L10 26.1 L15 27.0 L20 26.2 L25 24.1 L30 22.0 L35 21.0 L40 21.7 L45 23.7 L50 25.8 L55 27.0 L60 26.4 L65 24.5 L70 22.3 L75 21.1 L80 21.5 L85 23.3 L90 25.5 L95 26.9 L100 26.6 L105 24.9 L110 22.6 L115 21.2 L120 21.3 L125 22.9 L130 25.2 L135 26.8 L140 26.8 L145 25.2 L150 23.0 L155 21.3 L160 21.1 L165 22.6 L170 24.8 L175 26.6 L180 26.9 L185 25.6 L190 23.4 L195 21.5 L200 21.0"></path>
</g>
<g transform="translate(0 34)">
<path d="M0 16 L0 16.0 L5 20.9 L10 23.0 L15 21.2 L20 16.5 L25 11.5 L30 9.0 L35 10.5 L40 15.1 L45 20.2 L50 22.9 L55 21.7 L60 17.3 L65 12.2 L70 9.2 L75 10.0 L80 14.2 L85 19.4 L90 22.7 L95 22.2 L100 18.2 L105 13.0 L110 9.4 L115 9.6 L120 13.4 L125 18.6 L130 22.4 L135 22.6 L140 19.1 L145 13.8 L150 9.8 L155 9.3 L160 12.5 L165 17.7 L170 22.0 L175 22.8 L180 19.8 L185 14.7 L190 10.3 L195 9.1 L200 11.8"></path>
<path d="M0 18 L0 23.9 L5 23.0 L10 19.3 L15 14.9 L20 12.2 L25 12.8 L30 16.3 L35 20.8 L40 23.7 L45 23.4 L50 20.0 L55 15.5 L60 12.4 L65 12.4 L70 15.6 L75 20.1 L80 23.4 L85 23.7 L90 20.8 L95 16.3 L100 12.8 L105 12.2 L110 14.9 L115 19.4 L120 23.0 L125 23.9 L130 21.4 L135 17.0 L140 13.2 L145 12.1 L150 14.3 L155 18.6 L160 22.6 L165 24.0 L170 22.0 L175 17.8 L180 13.7 L185 12.0 L190 13.7 L195 17.8 L200 22.0"></path>
<path d="M0 20 L0 21.8 L5 18.1 L10 15.4 L15 15.3 L20 17.9 L25 21.6 L30 24.5 L35 24.8 L40 22.4 L45 18.7 L50 15.7 L55 15.1 L60 17.3 L65 21.0 L70 24.1 L75 24.9 L80 22.9 L85 19.3 L90 16.1 L95 15.0 L100 16.8 L105 20.4 L110 23.7 L115 25.0 L120 23.4 L125 20.0 L130 16.5 L135 15.0 L140 16.3 L145 19.7 L150 23.3 L155 25.0 L160 23.9 L165 20.6 L170 17.0 L175 15.1 L180 15.9 L185 19.1 L190 22.8 L195 24.9 L200 24.3"></path>
<path d="M0 22 L0 18.6 L5 18.1 L10 19.8 L15 22.7 L20 25.2 L25 26.0 L30 24.4 L35 21.5 L40 18.9 L45 18.0 L50 19.4 L55 22.2 L60 24.9 L65 26.0 L70 24.8 L75 22.1 L80 19.3 L85 18.0 L90 19.0 L95 21.7 L100 24.5 L105 26.0 L110 25.2 L115 22.6 L120 19.7 L125 18.1 L130 18.7 L135 21.2 L140 24.1 L145 25.9 L150 25.5 L155 23.1 L160 20.1 L165 18.2 L170 18.4 L175 20.7 L180 23.7 L185 25.7 L190 25.7 L195 23.6 L200 20.6"></path>
<path d="M0 24 L0 22.0 L5 24.1 L10 26.1 L15 27.0 L20 26.2 L25 24.1 L30 22.0 L35 21.0 L40 21.7 L45 23.7 L50 25.8 L55 27.0 L60 26.4 L65 24.5 L70 22.3 L75 21.1 L80 21.5 L85 23.3 L90 25.5 L95 26.9 L100 26.6 L105 24.9 L110 22.6 L115 21.2 L120 21.3 L125 22.9 L130 25.2 L135 26.8 L140 26.8 L145 25.2 L150 23.0 L155 21.3 L160 21.1 L165 22.6 L170 24.8 L175 26.6 L180 26.9 L185 25.6 L190 23.4 L195 21.5 L200 21.0"></path>
</g>
<g transform="translate(0 68)">
<path d="M0 16 L0 16.0 L5 20.9 L10 23.0 L15 21.2 L20 16.5 L25 11.5 L30 9.0 L35 10.5 L40 15.1 L45 20.2 L50 22.9 L55 21.7 L60 17.3 L65 12.2 L70 9.2 L75 10.0 L80 14.2 L85 19.4 L90 22.7 L95 22.2 L100 18.2 L105 13.0 L110 9.4 L115 9.6 L120 13.4 L125 18.6 L130 22.4 L135 22.6 L140 19.1 L145 13.8 L150 9.8 L155 9.3 L160 12.5 L165 17.7 L170 22.0 L175 22.8 L180 19.8 L185 14.7 L190 10.3 L195 9.1 L200 11.8"></path>
<path d="M0 18 L0 23.9 L5 23.0 L10 19.3 L15 14.9 L20 12.2 L25 12.8 L30 16.3 L35 20.8 L40 23.7 L45 23.4 L50 20.0 L55 15.5 L60 12.4 L65 12.4 L70 15.6 L75 20.1 L80 23.4 L85 23.7 L90 20.8 L95 16.3 L100 12.8 L105 12.2 L110 14.9 L115 19.4 L120 23.0 L125 23.9 L130 21.4 L135 17.0 L140 13.2 L145 12.1 L150 14.3 L155 18.6 L160 22.6 L165 24.0 L170 22.0 L175 17.8 L180 13.7 L185 12.0 L190 13.7 L195 17.8 L200 22.0"></path>
<path d="M0 20 L0 21.8 L5 18.1 L10 15.4 L15 15.3 L20 17.9 L25 21.6 L30 24.5 L35 24.8 L40 22.4 L45 18.7 L50 15.7 L55 15.1 L60 17.3 L65 21.0 L70 24.1 L75 24.9 L80 22.9 L85 19.3 L90 16.1 L95 15.0 L100 16.8 L105 20.4 L110 23.7 L115 25.0 L120 23.4 L125 20.0 L130 16.5 L135 15.0 L140 16.3 L145 19.7 L150 23.3 L155 25.0 L160 23.9 L165 20.6 L170 17.0 L175 15.1 L180 15.9 L185 19.1 L190 22.8 L195 24.9 L200 24.3"></path>
<path d="M0 22 L0 18.6 L5 18.1 L10 19.8 L15 22.7 L20 25.2 L25 26.0 L30 24.4 L35 21.5 L40 18.9 L45 18.0 L50 19.4 L55 22.2 L60 24.9 L65 26.0 L70 24.8 L75 22.1 L80 19.3 L85 18.0 L90 19.0 L95 21.7 L100 24.5 L105 26.0 L110 25.2 L115 22.6 L120 19.7 L125 18.1 L130 18.7 L135 21.2 L140 24.1 L145 25.9 L150 25.5 L155 23.1 L160 20.1 L165 18.2 L170 18.4 L175 20.7 L180 23.7 L185 25.7 L190 25.7 L195 23.6 L200 20.6"></path>
<path d="M0 24 L0 22.0 L5 24.1 L10 26.1 L15 27.0 L20 26.2 L25 24.1 L30 22.0 L35 21.0 L40 21.7 L45 23.7 L50 25.8 L55 27.0 L60 26.4 L65 24.5 L70 22.3 L75 21.1 L80 21.5 L85 23.3 L90 25.5 L95 26.9 L100 26.6 L105 24.9 L110 22.6 L115 21.2 L120 21.3 L125 22.9 L130 25.2 L135 26.8 L140 26.8 L145 25.2 L150 23.0 L155 21.3 L160 21.1 L165 22.6 L170 24.8 L175 26.6 L180 26.9 L185 25.6 L190 23.4 L195 21.5 L200 21.0"></path>
</g>
<g transform="translate(0 102)">
<path d="M0 16 L0 16.0 L5 20.9 L10 23.0 L15 21.2 L20 16.5 L25 11.5 L30 9.0 L35 10.5 L40 15.1 L45 20.2 L50 22.9 L55 21.7 L60 17.3 L65 12.2 L70 9.2 L75 10.0 L80 14.2 L85 19.4 L90 22.7 L95 22.2 L100 18.2 L105 13.0 L110 9.4 L115 9.6 L120 13.4 L125 18.6 L130 22.4 L135 22.6 L140 19.1 L145 13.8 L150 9.8 L155 9.3 L160 12.5 L165 17.7 L170 22.0 L175 22.8 L180 19.8 L185 14.7 L190 10.3 L195 9.1 L200 11.8"></path>
<path d="M0 18 L0 23.9 L5 23.0 L10 19.3 L15 14.9 L20 12.2 L25 12.8 L30 16.3 L35 20.8 L40 23.7 L45 23.4 L50 20.0 L55 15.5 L60 12.4 L65 12.4 L70 15.6 L75 20.1 L80 23.4 L85 23.7 L90 20.8 L95 16.3 L100 12.8 L105 12.2 L110 14.9 L115 19.4 L120 23.0 L125 23.9 L130 21.4 L135 17.0 L140 13.2 L145 12.1 L150 14.3 L155 18.6 L160 22.6 L165 24.0 L170 22.0 L175 17.8 L180 13.7 L185 12.0 L190 13.7 L195 17.8 L200 22.0"></path>
<path d="M0 20 L0 21.8 L5 18.1 L10 15.4 L15 15.3 L20 17.9 L25 21.6 L30 24.5 L35 24.8 L40 22.4 L45 18.7 L50 15.7 L55 15.1 L60 17.3 L65 21.0 L70 24.1 L75 24.9 L80 22.9 L85 19.3 L90 16.1 L95 15.0 L100 16.8 L105 20.4 L110 23.7 L115 25.0 L120 23.4 L125 20.0 L130 16.5 L135 15.0 L140 16.3 L145 19.7 L150 23.3 L155 25.0 L160 23.9 L165 20.6 L170 17.0 L175 15.1 L180 15.9 L185 19.1 L190 22.8 L195 24.9 L200 24.3"></path>
<path d="M0 22 L0 18.6 L5 18.1 L10 19.8 L15 22.7 L20 25.2 L25 26.0 L30 24.4 L35 21.5 L40 18.9 L45 18.0 L50 19.4 L55 22.2 L60 24.9 L65 26.0 L70 24.8 L75 22.1 L80 19.3 L85 18.0 L90 19.0 L95 21.7 L100 24.5 L105 26.0 L110 25.2 L115 22.6 L120 19.7 L125 18.1 L130 18.7 L135 21.2 L140 24.1 L145 25.9 L150 25.5 L155 23.1 L160 20.1 L165 18.2 L170 18.4 L175 20.7 L180 23.7 L185 25.7 L190 25.7 L195 23.6 L200 20.6"></path>
<path d="M0 24 L0 22.0 L5 24.1 L10 26.1 L15 27.0 L20 26.2 L25 24.1 L30 22.0 L35 21.0 L40 21.7 L45 23.7 L50 25.8 L55 27.0 L60 26.4 L65 24.5 L70 22.3 L75 21.1 L80 21.5 L85 23.3 L90 25.5 L95 26.9 L100 26.6 L105 24.9 L110 22.6 L115 21.2 L120 21.3 L125 22.9 L130 25.2 L135 26.8 L140 26.8 L145 25.2 L150 23.0 L155 21.3 L160 21.1 L165 22.6 L170 24.8 L175 26.6 L180 26.9 L185 25.6 L190 23.4 L195 21.5 L200 21.0"></path>
</g>
</svg>
<span class="cb-cheque__stub">
<b>No. 481</b>
To M. Holt
<br/>
Invoice 22
<br/>
$1,200.00
</span>
<span class="cb-cheque__holes"></span>
<span class="cb-cheque__bank">First Motion Bank</span>
<span class="cb-cheque__num">No. 481</span>
<span class="cb-cheque__amount">$1,200.00</span>
<span class="cb-cheque__row" style="top:46px;right:8px">
Pay
<i>Mira Holt</i>
</span>
<span class="cb-cheque__row" style="top:66px">
<i>One thousand two hundred only</i>
</span>
<span class="cb-cheque__line"></span>
<span class="cb-cheque__sign-label">Authorised signature</span>
<span class="cb-cheque__micr">⑆021000⑆ 8841 0327⑈ 481</span>
<svg class="cb-cheque__pen" viewBox="0 0 130 36">
<path class="cb-cheque__ink" pathLength="1" d="M4 30C10 12 15 4 17 8C19 14 13 30 16 31C20 28 24 14 28 12C31 12 27 28 30 29C34 28 36 20 40 19C43 20 39 28 43 28C47 27 50 17 53 8C55 3 57 6 55 14C53 22 52 28 55 28C59 27 62 20 64 21C66 24 64 29 67 28C72 26 74 18 80 10C76 22 76 30 80 29C84 26 88 22 94 22C104 22 112 20 124 15"></path>
</svg>
<span class="cb-cheque__stamp">PAID</span>
</span>
<span class="cb-cheque__flag">Sign here</span>
</span>
Sign and pay
</label>CSS
.cb-cheque { --paper: light-dark(#f3f4f7, #e5e6e9); --print: light-dark(#373a40, #121417); --soft: color-mix(in oklab, var(--print) 74%, var(--paper)); --flag: light-dark(#373a40, #232529); --flag-ink: light-dark(#fbfcfd, #f1f2f3); --hole: light-dark(#6d7179, #121417); flex: none; position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; color: light-dark(#42454c, #e5e6e9); font-size: 14px; font-weight: 500; cursor: pointer; -webkit-user-select: none; user-select: none; }
.cb-cheque__input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; }
.cb-cheque__art { position: relative; display: block; width: 268px; height: 152px; filter: drop-shadow(0 6px 8px rgba(0, 0, 0, 0.34)); transform: rotate(-1.4deg); }
.cb-cheque__input:focus-visible + .cb-cheque__art { outline: 2px solid light-dark(#5f626a, #a7abb2); outline-offset: 3px; border-radius: 6px; }
.cb-cheque__sheet { position: absolute; inset: 0; overflow: hidden; border-radius: 3px; background: var(--paper); color: var(--print); font-family: Georgia, 'Times New Roman', serif; }
.cb-cheque__wave { position: absolute; right: 0; top: 0; width: 212px; height: 100%; opacity: 0.2; fill: none; stroke: var(--print); stroke-width: 0.55; }
/* The tear-off stub, split from the cheque by a row of real holes. */
.cb-cheque__holes { position: absolute; left: 50px; top: 0; bottom: 0; width: 4px; background: radial-gradient(circle at 2px 3px, var(--hole) 1.3px, transparent 1.6px) 0 0 / 4px 6px; }
.cb-cheque__stub { position: absolute; left: 6px; top: 8px; width: 40px; font-size: 6.5px; line-height: 1.5; }
.cb-cheque__stub b { display: block; font-size: 10px; }
.cb-cheque__bank { position: absolute; left: 62px; top: 8px; font-size: 11.5px; font-weight: 700; letter-spacing: -0.01em; }
.cb-cheque__num { position: absolute; right: 8px; top: 9px; font: 700 8.5px 'Courier New', Courier, monospace; }
.cb-cheque__row { position: absolute; left: 62px; right: 8px; display: flex; align-items: flex-end; gap: 5px; font-size: 6.5px; letter-spacing: 0.02em; text-transform: uppercase; }
.cb-cheque__row i { flex: 1; min-width: 0; padding: 0 3px 1px; border-bottom: 1px solid var(--print); font: italic 700 11px/1.1 Georgia, 'Times New Roman', serif; letter-spacing: 0; text-transform: none; white-space: nowrap; overflow: hidden; }
.cb-cheque__amount { position: absolute; right: 8px; top: 26px; padding: 2px 5px; border: 1px solid var(--print); background: var(--paper); font: 700 11px 'Courier New', Courier, monospace; }
.cb-cheque__line { position: absolute; left: 150px; right: 10px; top: 110px; height: 1px; background: var(--print); }
.cb-cheque__sign-label { position: absolute; right: 10px; top: 112px; font-size: 6px; letter-spacing: 0.04em; text-transform: uppercase; }
.cb-cheque__micr { position: absolute; left: 62px; bottom: 7px; font: 700 8.5px 'Courier New', Courier, monospace; letter-spacing: 0.08em; }
.cb-cheque__pen { position: absolute; left: 134px; top: 82px; width: 130px; height: 36px; overflow: visible; fill: none; stroke: var(--print); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.cb-cheque__ink { stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0; transition: opacity 0.28s, stroke-dashoffset 0s 0.28s; }
.cb-cheque__input:checked + .cb-cheque__art .cb-cheque__ink { stroke-dashoffset: 0; opacity: 1; transition: stroke-dashoffset 0.85s cubic-bezier(0.35, 0.1, 0.6, 1) 0.18s, opacity 0s; }
.cb-cheque__flag { position: absolute; left: 86px; top: 100px; display: flex; align-items: center; height: 19px; padding: 0 13px 0 8px; background: var(--flag); color: var(--flag-ink); clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%); font: 700 9.5px system-ui, sans-serif; white-space: nowrap; transform-origin: 0 50%; transition: transform 0.3s cubic-bezier(0.3, 1.5, 0.5, 1), opacity 0.2s; }
.cb-cheque:hover .cb-cheque__flag { transform: translateX(4px); }
.cb-cheque__input:checked + .cb-cheque__art .cb-cheque__flag { transform: translate(-28px, 34px) rotate(-30deg) scale(0.9); opacity: 0; transition: transform 0.36s ease-in, opacity 0.2s 0.14s; }
.cb-cheque__stamp { position: absolute; left: 68px; top: 88px; padding: 3px 9px; border: 2.5px solid var(--print); border-radius: 4px; color: var(--print); font: 900 18px/1 'Arial Black', Impact, system-ui, sans-serif; letter-spacing: 0.08em; opacity: 0; transform: rotate(-11deg) scale(1.9); transition: opacity 0.12s, transform 0.12s; }
.cb-cheque__input:checked + .cb-cheque__art .cb-cheque__stamp { opacity: 0.78; transform: rotate(-11deg); transition: opacity 0.06s 1.02s, transform 0.16s cubic-bezier(0.5, 0, 1, 0.6) 1.02s; }
.cb-cheque__input:checked + .cb-cheque__art { animation: cb-cheque-thud 0.3s cubic-bezier(0.3, 1.6, 0.5, 1) 1.17s; }
@keyframes cb-cheque-thud {
0% { transform: rotate(-1.4deg) translateY(3px) scale(0.99); }
100% { transform: rotate(-1.4deg); }
}
@media (prefers-reduced-motion: reduce) {
.cb-cheque *, .cb-cheque__input:checked + .cb-cheque__art, .cb-cheque__input:checked + .cb-cheque__art * { animation: none !important; transition: none !important; }
}Goal: Create a "Cheque" checkbox.
Visual behavior: The other kind of check. A proper paper cheque with fine print and perforations: tick it, the Sign here flag peels away, a signature writes itself and a PAID stamp lands.
Technique:
- The signature is one long stroke drawn in by its dash offset. The flag, the ink and the stamp share one clock through transition delays: the flag goes first, the ink follows, then the stamp comes down hard from a bigger size and a small keyframe thuds the whole cheque as it lands.
- The security pattern is a stack of fine wave paths, and the stub is torn off along a line of small round holes. Pure CSS.
Accessibility: A native checkbox inside a <label>, so "Sign and pay" is its name. The cheque is aria-hidden and keyboard focus outlines it. Under prefers-reduced-motion the signature and the stamp appear at once.
My stack: {{USER_STACK}}
My styling: {{USER_STYLING}}
My constraints: {{USER_CONSTRAINTS}}
My colors: neutral only. Black, white and grays, no hues. Use the color values above as written, or my project's closest neutral tokens.
Return a single self-contained component. No dependencies.Goal: Create a "Cheque" checkbox.
Visual behavior: The other kind of check. A proper paper cheque with fine print and perforations: tick it, the Sign here flag peels away, a signature writes itself and a PAID stamp lands.
Technique:
- The signature is one long stroke drawn in by its dash offset. The flag, the ink and the stamp share one clock through transition delays: the flag goes first, the ink follows, then the stamp comes down hard from a bigger size and a small keyframe thuds the whole cheque as it lands.
- The security pattern is a stack of fine wave paths, and the stub is torn off along a line of small round holes. Pure CSS.
Accessibility: A native checkbox inside a <label>, so "Sign and pay" is its name. The cheque is aria-hidden and keyboard focus outlines it. Under prefers-reduced-motion the signature and the stamp appear at once.
My stack: {{USER_STACK}}
My styling: {{USER_STYLING}}
My constraints: {{USER_CONSTRAINTS}}
My colors: use my project's existing color tokens. The color values above are grayscale placeholders. Map each one by its role (surface, text, border, accent, glow) to my theme, and keep their relative lightness so contrast and the effect still read.
Return a single self-contained component. No dependencies.Paste into Claude, ChatGPT or Cursor after filling in {{USER_STACK}}, {{USER_STYLING}} and {{USER_CONSTRAINTS}}. Neutral keeps the greys you see here; Match my project asks the model to map them onto your own colour tokens.
Free to use in any project, commercial included. MIT-0, no attribution required. Licence
About this component
The other kind of check. A proper paper cheque with fine print and perforations: tick it, the Sign here flag peels away, a signature writes itself and a PAID stamp lands.
- Dependencies
- None
- Difficulty
- Intermediate
- Triggers
- click, state change, draw, keyframe
- Techniques
- stroke dashoffset, css transition, keyframes, svg, css variables
- Reduced motion
- Respected
- Theme
- Light and dark (follows your page's color-scheme)
A native checkbox inside a <label>, so "Sign and pay" is its name. The cheque is aria-hidden and keyboard focus outlines it. Under prefers-reduced-motion the signature and the stamp appear at once.