← quik.run
NP@naman-parashar-s-team / Vercel CardPublic

Vercel Card

A JS snippet on QuikRun, callable at quik.run/r/vercel-card.

JS· node:20· 178 runs· 0 forks· updated 23h ago
Endpointquik.run/r/vercel-cardRunFork
Vercel Card.js
// QuikRun · Vercel Card
//
// What if Vercel shipped a metal card. Black anodised titanium, etched
// triangle, Geist type.
//
// The holographic treatment follows simeydotme/pokemon-cards-css: a stack of
// grid-area:1/1 layers (art → shine → glare) blended with color-dodge and
// overlay, driven by CSS custom properties that JS updates from the pointer.
// The trick that sells it is parallax — the holo pattern is positioned from
// --bg-x/--bg-y, which is the pointer remapped to a much narrower range, so
// the pattern drifts slower than the cursor and reads as depth under glass.
 
const LIVE = "https://quik.run/r/vercel-card";
const OG = "https://quik.run/brand/quikrun-mark-fullbleed-512.png";
const TITLE = "Vercel Card";
 
const HOLDER = "NAMAN PARASHAR";
const HANDLE = "@nparashar150";
 
const CSS = `
:root{
/* pointer-driven, mirrors the pokemon-cards-css variable contract */
--pointer-x:50%;
--pointer-y:50%;
--bg-x:50%;
--bg-y:50%;
--pointer-from-center:0;
--pointer-from-top:.5;
--pointer-from-left:.5;
--card-opacity:0;
--rotate-x:0deg;
--rotate-y:0deg;
--flip:0deg;
 
--sans:"Geist",-apple-system,BlinkMacSystemFont,ui-sans-serif,system-ui,sans-serif;
--mono:"Geist Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
 
/* sunpillar ramp, desaturated for anodised black rather than foil */
--sp1:hsl(2,85%,68%);
--sp2:hsl(46,90%,68%);
--sp3:hsl(150,80%,66%);
--sp4:hsl(186,90%,70%);
--sp5:hsl(226,90%,72%);
--sp6:hsl(288,85%,70%);
 
--card-radius:3.6%/5.6%;
--thick:5px;
--half:2.5px;
--lift:0px;
--flip-cos:1;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{
height:100%;overflow:hidden;
user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;
}
body{
height:100dvh;display:grid;place-items:center;
padding:max(16px,env(safe-area-inset-top)) 18px max(16px,env(safe-area-inset-bottom));
background:#000;
font-family:var(--sans);
-webkit-font-smoothing:antialiased;
color:#ededed;
}
/* Vercel-style backdrop: pure black with a single soft ellipse of light. */
.backdrop{
position:fixed;inset:0;z-index:0;pointer-events:none;
background:
radial-gradient(46% 34% at 50% 26%,rgba(120,140,180,.16) 0%,transparent 70%),
radial-gradient(80% 60% at 50% 120%,rgba(0,0,0,1) 0%,transparent 60%),
#000;
}
.backdrop::after{
content:"";position:absolute;inset:0;
background-image:linear-gradient(to right,rgba(255,255,255,.035) 1px,transparent 1px),
linear-gradient(to bottom,rgba(255,255,255,.035) 1px,transparent 1px);
background-size:56px 56px;
mask-image:radial-gradient(58% 48% at 50% 42%,#000 0%,transparent 78%);
-webkit-mask-image:radial-gradient(58% 48% at 50% 42%,#000 0%,transparent 78%);
}
 
.wrap{
position:relative;z-index:1;
display:flex;flex-direction:column;align-items:center;
gap:clamp(14px,3vh,30px);
width:100%;
}
 
/* ---------- masthead ---------- */
.masthead{display:flex;align-items:center;gap:9px}
.masthead svg{display:block;width:15px;height:auto}
.masthead b{font-size:15px;font-weight:600;letter-spacing:-.02em}
.masthead span{
font-family:var(--mono);font-size:10px;font-weight:500;
letter-spacing:.14em;text-transform:uppercase;color:#8f8f8f;
padding-left:9px;margin-left:2px;border-left:1px solid #2e2e2e;
}
 
/* ---------- stage / card ---------- */
.scene{
position:relative;
perspective:1600px;perspective-origin:50% 50%;
width:min(520px,90vw,calc((100dvh - 12rem) * 1.586));
}
/* Cast shadow lives outside the rotating slab and squeezes with the card's
facing angle, so the flip is grounded instead of floating. */
.shadow{
position:absolute;z-index:0;pointer-events:none;
left:-2%;right:-2%;top:16%;bottom:-16%;
background:radial-gradient(50% 50% at 50% 52%,rgba(0,0,0,.95) 0%,rgba(0,0,0,.6) 38%,transparent 74%);
filter:blur(26px);
transform:scaleX(calc(.3 + var(--flip-cos) * .7));
opacity:calc(.42 + var(--flip-cos) * .58);
}
.card{
position:relative;width:100%;aspect-ratio:1.586;
transform-style:preserve-3d;
/* lift toward the viewer through the turn, the way you'd raise a card off a
table to flip it, then set it back down */
transform:
translateZ(var(--lift,0px))
rotateY(calc(var(--rotate-x) + var(--flip)))
rotateX(var(--rotate-y));
will-change:transform;
cursor:pointer;outline:none;
border-radius:var(--card-radius);
}
.card:focus-visible{outline:2px solid #fff;outline-offset:14px;border-radius:4px}
 
.face{
position:absolute;inset:0;
display:grid;
border-radius:var(--card-radius);
overflow:hidden;
box-shadow:
0 1px 0 0 rgba(255,255,255,.16),
0 0 0 1px rgba(0,0,0,.9);
}
.face > *{grid-area:1/1;border-radius:inherit}
.side{
position:absolute;inset:0;
border-radius:var(--card-radius);
backface-visibility:hidden;-webkit-backface-visibility:hidden;
}
.side-back{transform:rotateY(180deg)}
 
/* ---------- machined edge ------------------------------------------------
Without these the card is a zero-thickness plane and vanishes completely at
90deg, which is the single biggest tell that a flip is faked. Four strips
bridge the two faces so the milled edge stays visible right through the turn. */
.edge{
position:absolute;display:block;pointer-events:none;
backface-visibility:visible;-webkit-backface-visibility:visible;
}
.edge-l,.edge-r{
top:3.4%;bottom:3.4%;width:var(--thick);
background:linear-gradient(180deg,#8f8f8f 0%,#3a3a3a 16%,#c2c2c2 46%,#4a4a4a 58%,#242424 82%,#111 100%);
}
.edge-l{left:0;transform:translateX(calc(var(--half) * -1)) rotateY(-90deg)}
.edge-r{right:0;transform:translateX(var(--half)) rotateY(90deg)}
.edge-t,.edge-b{
left:2.4%;right:2.4%;height:var(--thick);
background:linear-gradient(90deg,#3a3a3a 0%,#a8a8a8 22%,#454545 48%,#9a9a9a 70%,#2a2a2a 88%,#141414 100%);
}
.edge-t{top:0;transform:translateY(calc(var(--half) * -1)) rotateX(90deg)}
.edge-b{bottom:0;transform:translateY(var(--half)) rotateX(-90deg)}
 
/* ---------- anodised black plate ---------- */
.plate{
background:
radial-gradient(120% 90% at 12% 0%,rgba(255,255,255,.16) 0%,transparent 46%),
radial-gradient(90% 80% at 92% 100%,rgba(0,0,0,.75) 0%,transparent 52%),
linear-gradient(148deg,#232323 0%,#141414 38%,#1c1c1c 60%,#0d0d0d 100%);
}
/* fine brushed grain */
.plate::after{
content:"";position:absolute;inset:0;border-radius:inherit;
background:repeating-linear-gradient(96deg,
rgba(255,255,255,.035) 0px,rgba(255,255,255,.035) 1px,
transparent 1px,transparent 3px);
opacity:.5;
}
/* light sweep that tracks the pointer across the metal */
.sweep{
background:linear-gradient(
calc(120deg + (var(--pointer-from-left) * 40deg)),
transparent 32%,
rgba(255,255,255,.10) calc(46% + (var(--pointer-from-left) * 8%)),
rgba(255,255,255,.02) 58%,
transparent 70%);
opacity:calc(.5 + var(--card-opacity) * .5);
mix-blend-mode:screen;
}
.bevel{
box-shadow:
inset 0 1px 0 rgba(255,255,255,.22),
inset 1px 0 0 rgba(255,255,255,.08),
inset -1px 0 0 rgba(0,0,0,.6),
inset 0 -1px 0 rgba(0,0,0,.8);
pointer-events:none;
}
 
/* ---------- holo shine (pokemon-cards-css technique) ---------- */
.shine{
z-index:3;
background-image:
repeating-linear-gradient(110deg,
var(--sp6),var(--sp5),var(--sp4),var(--sp3),var(--sp2),var(--sp1),
var(--sp6),var(--sp5),var(--sp4),var(--sp3),var(--sp2),var(--sp1),
var(--sp6),var(--sp5),var(--sp4),var(--sp3),var(--sp2),var(--sp1)),
repeating-linear-gradient(90deg,
#101010 0px,#101010 2px,#2e2e2e 2px,#2e2e2e 5px);
background-position:
calc(((50% - var(--bg-x)) * 2.6) + 50%) calc(((50% - var(--bg-y)) * 3.5) + 50%),
center center;
background-size:380% 380%,cover;
background-blend-mode:overlay;
filter:brightness(.62) contrast(1.5) saturate(.75);
mix-blend-mode:color-dodge;
opacity:calc(var(--card-opacity) * .5);
/* pool the iridescence where the light actually falls */
-webkit-mask-image:radial-gradient(farthest-corner circle at var(--pointer-x) var(--pointer-y),
#000 0%,rgba(0,0,0,.6) 26%,rgba(0,0,0,.16) 48%,transparent 68%);
mask-image:radial-gradient(farthest-corner circle at var(--pointer-x) var(--pointer-y),
#000 0%,rgba(0,0,0,.6) 26%,rgba(0,0,0,.16) 48%,transparent 68%);
}
/* second pillar pass, offset and counter-rotated for interference */
.shine::after{
content:"";position:absolute;inset:0;border-radius:inherit;
background-image:
repeating-linear-gradient(-72deg,
var(--sp2),var(--sp3),var(--sp4),var(--sp5),var(--sp6),var(--sp1),
var(--sp2),var(--sp3),var(--sp4),var(--sp5),var(--sp6),var(--sp1));
background-position:
calc(((50% - var(--bg-x)) * -1.4) + 50%) calc(((50% - var(--bg-y)) * -1.9) + 50%);
background-size:300% 300%;
mix-blend-mode:color-dodge;
opacity:.32;
}
.back .shine{opacity:calc(var(--card-opacity) * .85)}
.back .shine::after{opacity:.5}
/* ---------- glare ---------- */
.glare{
z-index:4;
background-image:radial-gradient(
farthest-corner circle at var(--pointer-x) var(--pointer-y),
rgba(255,255,255,.55) 6%,
rgba(255,255,255,.22) 24%,
rgba(0,0,0,.35) 100%);
mix-blend-mode:overlay;
opacity:calc(var(--card-opacity) * .8);
}
 
/* ---------- front content ---------- */
.content{z-index:2;position:relative;padding:5.4% 6%;display:flex;flex-direction:column}
.row{display:flex;align-items:flex-start;justify-content:space-between}
.brandline{display:flex;align-items:center;gap:7px}
.brandline svg{display:block;width:clamp(11px,2.4vw,14px);height:auto}
.brandline b{
font-size:clamp(12px,2.8vw,15px);font-weight:600;letter-spacing:-.02em;color:#f2f2f2;
}
.tier{
font-family:var(--mono);font-size:clamp(6.5px,1.5vw,8px);font-weight:500;
letter-spacing:.22em;text-transform:uppercase;color:#8a8a8a;
}
 
/* EMV chip */
.chip{
margin-top:auto;width:clamp(38px,9.4vw,54px);height:auto;display:block;
}
 
/* etched triangle, built from three offset clip-path layers so the bevel
catches light on one facet and falls into shadow on the other */
.mark{
position:absolute;
right:7.5%;top:50%;transform:translateY(-50%);
width:34%;aspect-ratio:1.155;
pointer-events:none;
}
.mark i{position:absolute;inset:0;clip-path:polygon(50% 2%,100% 98%,0% 98%);display:block}
.mark .hi{
transform:translate(calc(-2px + (var(--pointer-from-left) * 2px)),-2px);
background:linear-gradient(150deg,#c8c8c8 0%,#6e6e6e 44%,#3a3a3a 100%);
}
.mark .lo{
transform:translate(2px,2px);
background:#000;
}
.mark .fc{
background:
linear-gradient(calc(140deg + (var(--pointer-from-left) * 60deg)),
#3a3a3a 0%,#191919 38%,#242424 62%,#101010 100%);
}
.mark .gl{
background:linear-gradient(
calc(150deg + (var(--pointer-from-left) * 50deg)),
transparent 34%,
rgba(255,255,255,calc(.16 + var(--card-opacity) * .3)) 50%,
transparent 64%);
mix-blend-mode:screen;
}
 
/* ---------- back content ---------- */
.back .content{padding:5.4% 6%}
/* --- Geist back ---------------------------------------------------------
Geist calls the grid a core part of the Vercel aesthetic, so the back is a
guide grid engraved into the metal (dark line + light line offset by 1px)
carrying a GridCell-style panel. The system is deliberately achromatic:
colour is reserved for status indicators and never used decoratively, so
the only chromatic pixel on this card is the 6px Ready dot. */
.guides{
position:absolute;inset:0;z-index:1;pointer-events:none;
background-image:
linear-gradient(to right,rgba(0,0,0,.42) 1px,transparent 1px),
linear-gradient(to bottom,rgba(0,0,0,.42) 1px,transparent 1px);
background-size:10% 16.667%;
-webkit-mask-image:radial-gradient(96% 78% at 50% 44%,#000 8%,rgba(0,0,0,.5) 52%,transparent 88%);
mask-image:radial-gradient(96% 78% at 50% 44%,#000 8%,rgba(0,0,0,.5) 52%,transparent 88%);
}
.guides::after{
content:"";position:absolute;inset:0;
background-image:
linear-gradient(to right,rgba(255,255,255,.052) 1px,transparent 1px),
linear-gradient(to bottom,rgba(255,255,255,.052) 1px,transparent 1px);
background-size:10% 16.667%;
transform:translate(1px,1px);
}
 
.back .content{gap:0}
.backhead{display:flex;align-items:flex-start;justify-content:space-between}
.backhead .mini{display:block;width:clamp(9px,2vw,12px);height:auto;color:#8f8f8f}
 
/* Geist GridCell panel. 6px is the system's default component radius. */
.cells{
margin-top:auto;
display:grid;grid-template-columns:repeat(3,1fr);
border:1px solid rgba(255,255,255,.13);
border-radius:6px;
background:rgba(10,10,10,.55);
overflow:hidden;
}
.cell{padding:clamp(7px,1.9vw,13px) clamp(8px,2.1vw,15px)}
.cell + .cell{border-left:1px solid rgba(255,255,255,.10)}
.cell .k{
font-family:var(--mono);font-size:clamp(6px,1.45vw,8.5px);font-weight:500;
letter-spacing:.14em;text-transform:uppercase;color:#a1a1a1;
}
.cell .v{
margin-top:clamp(2px,.7vw,5px);
font-family:var(--mono);font-size:clamp(8px,2vw,12px);font-weight:500;
letter-spacing:-.01em;color:#ededed;
display:flex;align-items:center;gap:5px;white-space:nowrap;
}
.dot{
flex:none;width:clamp(4px,.95vw,6px);aspect-ratio:1;border-radius:9999px;
background:#45de80;box-shadow:0 0 6px rgba(69,222,128,.55);
}
 
.backfoot{
margin-top:clamp(9px,2.4vw,16px);
display:flex;align-items:flex-end;justify-content:space-between;gap:14px;
}
.nfc{display:block;height:clamp(16px,3.8vw,24px);width:auto;opacity:.6}
.holder{margin-top:clamp(10px,2.6vw,18px)}
.holder .nm{
font-size:clamp(12px,3vw,16px);font-weight:500;letter-spacing:-.01em;color:#f2f2f2;
}
.holder .hd{
margin-top:2px;
font-family:var(--mono);font-size:clamp(9.5px,2.3vw,12px);color:#a1a1a1;
}
.payment{text-align:right;display:flex;flex-direction:column;align-items:flex-end;gap:3px}
.payment .visa{
font-size:clamp(15px,4vw,23px);font-weight:700;font-style:italic;
letter-spacing:-.03em;color:#f2f2f2;
}
.payment .kind{
font-family:var(--mono);font-size:clamp(6.5px,1.5vw,8.5px);
letter-spacing:.16em;text-transform:uppercase;color:#9a9a9a;
}
 
/* ---------- caption ---------- */
.caption{
display:flex;align-items:center;gap:9px;
font-family:var(--mono);font-size:10px;
letter-spacing:.14em;text-transform:uppercase;color:#7a7a7a;
}
.caption b{color:#ededed;font-weight:500}
.caption s{width:3px;height:3px;border-radius:99px;background:#333;text-decoration:none}
 
@media (prefers-reduced-motion:reduce){
.card{transform:rotateY(var(--flip))}
}
`;
 
const TRIANGLE = `<svg viewBox="0 0 76 65" fill="none" aria-hidden="true"><path d="M37.59.25l36.95 64H.64l36.95-64z" fill="currentColor"/></svg>`;
 
const CHIP = `<svg class="chip" viewBox="0 0 50 40" aria-hidden="true">
<defs>
<linearGradient id="chipg" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#d8d8d8"/>
<stop offset="30%" stop-color="#8e8e8e"/>
<stop offset="58%" stop-color="#cfcfcf"/>
<stop offset="100%" stop-color="#6a6a6a"/>
</linearGradient>
</defs>
<rect x=".4" y=".4" width="49.2" height="39.2" rx="6.4" fill="#000" fill-opacity=".5"/>
<rect x="1.6" y="1.6" width="46.8" height="36.8" rx="5.2" fill="url(#chipg)" stroke="#4a4a4a" stroke-width=".8"/>
<g fill="none" stroke="#3d3d3d" stroke-width="1.3">
<path d="M2.2 10.6H47.8"/><path d="M2.2 20H47.8"/><path d="M2.2 29.4H47.8"/><path d="M25 2.2V37.8"/>
</g>
<path d="M25.9 2.9V37.1M2.9 11.3H47.1M2.9 20.7H47.1M2.9 30.1H47.1" fill="none" stroke="#f2f2f2" stroke-opacity=".22" stroke-width=".6"/>
</svg>`;
 
const NFC = `<svg class="nfc" viewBox="0 0 20 24" fill="none" aria-hidden="true">
<g stroke="#ededed" stroke-width="1.9" stroke-linecap="round">
<path d="M4 16.2a6.2 6.2 0 0 0 0-8.4"/>
<path d="M9 19.1a10.6 10.6 0 0 0 0-14.2" stroke-opacity=".68"/>
<path d="M14 22a15 15 0 0 0 0-20" stroke-opacity=".42"/>
</g>
</svg>`;
 
const SCRIPT = `
(function () {
var scene = document.getElementById("scene");
var card = document.getElementById("card");
var caption = document.getElementById("caption-face");
if (!scene || !card) return;
 
var reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
 
var clamp = function (v, min, max) { return Math.min(Math.max(v, min == null ? 0 : min), max == null ? 100 : max); };
var round = function (v, p) { p = p || 3; return parseFloat(v.toFixed(p)); };
/* remap a 0-100 pointer value into a narrower band, so the holo pattern
drifts slower than the cursor. straight out of pokemon-cards-css. */
var adjust = function (v, fromMin, fromMax, toMin, toMax) {
return round(toMin + (toMax - toMin) * (v - fromMin) / (fromMax - fromMin));
};
 
var target = { px: 50, py: 50, bx: 50, by: 50, rx: 0, ry: 0, o: 0 };
var current = { px: 50, py: 50, bx: 50, by: 50, rx: 0, ry: 0, o: 0 };
var flip = { v: 0, t: 0, vel: 0 };
var raf = null;
 
function apply() {
var s = card.style;
s.setProperty("--pointer-x", current.px + "%");
s.setProperty("--pointer-y", current.py + "%");
s.setProperty("--bg-x", current.bx + "%");
s.setProperty("--bg-y", current.by + "%");
s.setProperty("--rotate-x", current.rx + "deg");
s.setProperty("--rotate-y", current.ry + "deg");
s.setProperty("--card-opacity", current.o);
s.setProperty("--pointer-from-left", round(current.px / 100));
s.setProperty("--pointer-from-top", round(current.py / 100));
s.setProperty("--pointer-from-center",
round(clamp(Math.sqrt(
(current.py - 50) * (current.py - 50) + (current.px - 50) * (current.px - 50)
) / 50, 0, 1)));
var deg = flip.v * 180;
var rad = deg * Math.PI / 180;
s.setProperty("--flip", round(deg) + "deg");
/* peaks at 90deg, so the card rises as it turns and settles as it lands */
s.setProperty("--lift", round(Math.abs(Math.sin(rad)) * 42) + "px");
/* 1 face-on, 0 edge-on drives the cast shadow */
s.setProperty("--flip-cos", round(Math.abs(Math.cos(rad)), 4));
card.classList.toggle("showing-back", flip.v >= 0.5);
}
 
function tick() {
var k = 0.14, done = true;
for (var key in target) {
var d = target[key] - current[key];
if (Math.abs(d) > 0.01) { current[key] = round(current[key] + d * k); done = false; }
else current[key] = target[key];
}
/* A spring, not an ease. Real objects carry momentum and overshoot a touch
before settling; symmetric easing is what made the turn read as canned. */
flip.vel = (flip.vel + (flip.t - flip.v) * 0.006) * 0.90;
if (Math.abs(flip.vel) > 0.00002 || Math.abs(flip.t - flip.v) > 0.0002) {
flip.v = round(flip.v + flip.vel, 5); done = false;
} else { flip.v = flip.t; flip.vel = 0; }
apply();
raf = done ? null : requestAnimationFrame(tick);
}
function kick() { if (raf === null) raf = requestAnimationFrame(tick); }
 
function interact(e) {
if (reduced) return;
var rect = card.getBoundingClientRect();
var absX = e.clientX - rect.left;
var absY = e.clientY - rect.top;
var percentX = clamp(round((100 / rect.width) * absX));
var percentY = clamp(round((100 / rect.height) * absY));
var centerX = percentX - 50;
var centerY = percentY - 50;
 
target.px = percentX;
target.py = percentY;
target.bx = adjust(percentX, 0, 100, 37, 63);
target.by = adjust(percentY, 0, 100, 33, 67);
target.rx = round(-(centerX / 4));
target.ry = round(centerY / 5);
target.o = 1;
kick();
}
function release() {
target.px = 50; target.py = 50;
target.bx = 50; target.by = 50;
target.rx = 0; target.ry = 0; target.o = 0;
kick();
}
 
scene.addEventListener("pointermove", interact);
scene.addEventListener("pointerenter", interact);
scene.addEventListener("pointerleave", release);
 
function toggleFlip() {
flip.t = flip.t > 0.5 ? 0 : 1;
card.setAttribute("aria-pressed", flip.t > 0.5 ? "true" : "false");
if (caption) caption.textContent = flip.t > 0.5 ? "Back" : "Front";
kick();
}
card.addEventListener("click", toggleFlip);
card.addEventListener("keydown", function (e) {
if (e.key === "Enter" || e.key === " ") { e.preventDefault(); toggleFlip(); }
});
 
apply();
})();
`;
 
function page() {
return `<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>${TITLE}</title>
<meta name="description" content="What if Vercel shipped a metal card. Holographic, pointer-reactive, built in one QuikRun snippet." />
<meta property="og:title" content="${TITLE}" />
<meta property="og:url" content="${LIVE}" />
<meta property="og:image" content="${OG}" />
<meta name="theme-color" content="#000000" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet" />
<style>${CSS}</style>
</head>
<body>
<div class="backdrop" aria-hidden="true"></div>
 
<div class="wrap">
<header class="masthead">
${TRIANGLE.replace('aria-hidden="true"', 'aria-hidden="true" style="color:#ededed"')}
<b>Vercel</b>
<span>Card</span>
</header>
 
<div class="scene" id="scene">
<div class="shadow" aria-hidden="true"></div>
<article class="card" id="card" role="button" tabindex="0"
aria-label="Vercel card move to tilt, click to flip" aria-pressed="false">
 
<div class="side side-front"><div class="face front">
<div class="plate"></div>
<div class="sweep"></div>
<div class="content">
<div class="row">
<div class="brandline">
${TRIANGLE}
<b>Vercel</b>
</div>
<div class="tier">Infinite</div>
</div>
${CHIP}
</div>
<div class="mark" aria-hidden="true">
<i class="hi"></i><i class="lo"></i><i class="fc"></i><i class="gl"></i>
</div>
<div class="shine"></div>
<div class="glare"></div>
<div class="bevel"></div>
</div></div>
 
<div class="side side-back"><div class="face back">
<div class="plate"></div>
<div class="sweep"></div>
<div class="guides"></div>
<div class="content">
<div class="backhead">
${NFC}
${TRIANGLE.replace('aria-hidden="true"', 'class="mini" aria-hidden="true"')}
</div>
 
<div class="cells">
<div class="cell">
<div class="k">Region</div>
<div class="v">bom1</div>
</div>
<div class="cell">
<div class="k">Status</div>
<div class="v"><i class="dot"></i>Ready</div>
</div>
<div class="cell">
<div class="k">Member</div>
<div class="v">2024</div>
</div>
</div>
 
<div class="backfoot">
<div class="holder">
<div class="nm">${HOLDER}</div>
<div class="hd">${HANDLE}</div>
</div>
<div class="payment">
<div class="visa">VISA</div>
<div class="kind">Debit / Edge</div>
</div>
</div>
</div>
<div class="shine"></div>
<div class="glare"></div>
<div class="bevel"></div>
</div></div>
 
<i class="edge edge-l" aria-hidden="true"></i>
<i class="edge edge-r" aria-hidden="true"></i>
<i class="edge edge-t" aria-hidden="true"></i>
<i class="edge edge-b" aria-hidden="true"></i>
</article>
</div>
 
<p class="caption">
<span>Move to tilt</span><s></s>
<span>Click to flip</span><s></s>
<b id="caption-face">Front</b>
</p>
</div>
 
<script>${SCRIPT}</script>
</body>
</html>`;
}
 
export default async function handler() {
return new Response(page(), {
status: 200,
headers: {
"content-type": "text/html; charset=utf-8",
"cache-control": "no-store",
},
});
}
 
Fork this and make it yours

Describe a change in plain English and QuikRun deploys it to your own URL.

Fork snippet

Built on QuikRun by @naman-parashar-s-team · plain English in, live URL out