← quik.run
NP@naman-parashar-s-team / Naman Parashar · Gold CardPublic

Naman Parashar · Gold Card

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

JS· node:20· 38 runs· 0 forks· updated 3m ago
Endpointquik.run/r/quikrun-metal-cardRunFork
Naman Parashar · Gold Card.js
// QuikRun · Metal Card — NAMAN PARASHAR
// Layout is the CSS plate (gold / silver). WebGL is a blend overlay only:
// grain + anisotropic sweep + cursor specular. It must never own the design.
import htm from "htm";
void htm;
 
const LIVE = "https://quik.run/r/quikrun-metal-card";
const OG = "https://quik.run/brand/quikrun-mark-fullbleed-512.png";
const NAME = "NAMAN PARASHAR";
 
const CHIP = `<svg class="chip" viewBox="0 0 52 40" aria-hidden="true">
<defs>
<linearGradient id="cg" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#f3e7c4"/>
<stop offset="35%" stop-color="#c4a04a"/>
<stop offset="55%" stop-color="#ecd9a0"/>
<stop offset="100%" stop-color="#9a7830"/>
</linearGradient>
<linearGradient id="cs" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#f2f3f5"/>
<stop offset="35%" stop-color="#b4b8be"/>
<stop offset="55%" stop-color="#e4e6ea"/>
<stop offset="100%" stop-color="#8a9098"/>
</linearGradient>
<linearGradient id="cp" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#6a5428"/>
<stop offset="40%" stop-color="#3d3014"/>
<stop offset="100%" stop-color="#5c4820"/>
</linearGradient>
<linearGradient id="cps" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#6a6e74"/>
<stop offset="40%" stop-color="#2e3238"/>
<stop offset="100%" stop-color="#555a62"/>
</linearGradient>
</defs>
<rect class="chip-body" x="1" y="1" width="50" height="38" rx="5" fill="url(#cg)" stroke="#6a5220" stroke-width="1"/>
<rect x="2.2" y="2.2" width="47.6" height="35.6" rx="4" fill="none" stroke="#fff6d0" stroke-opacity=".35" stroke-width=".6"/>
<g class="chip-pads" fill="url(#cp)">
<rect x="7" y="7" width="11" height="7" rx="1.1"/>
<rect x="20.5" y="7" width="11" height="7" rx="1.1"/>
<rect x="34" y="7" width="11" height="7" rx="1.1"/>
<rect x="7" y="16.5" width="11" height="7" rx="1.1"/>
<rect x="34" y="16.5" width="11" height="7" rx="1.1"/>
<rect x="20.5" y="16.5" width="11" height="7" rx="1.1"/>
<rect x="7" y="26" width="11" height="7" rx="1.1"/>
<rect x="20.5" y="26" width="11" height="7" rx="1.1"/>
<rect x="34" y="26" width="11" height="7" rx="1.1"/>
</g>
</svg>`;
 
const CSS = `
:root{
--mx:48%; --my:38%; --shine:0; --rx:0deg; --ry:0deg;
--display:"Outfit",ui-sans-serif,system-ui,sans-serif;
--mono:"IBM Plex Mono",ui-monospace,Menlo,monospace;
}
*{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(10px,env(safe-area-inset-top)) 14px max(10px,env(safe-area-inset-bottom));
background:radial-gradient(55% 45% at 50% 42%,#2a2a2e 0%,#141416 55%,#0a0a0c 100%);
font-family:var(--display);-webkit-font-smoothing:antialiased;
}
.wrap{
width:100%;max-height:100%;
display:flex;flex-direction:column;align-items:center;justify-content:center;
gap:clamp(10px,2.2vh,20px);
}
.picker{display:flex;gap:8px;z-index:6;flex-shrink:0}
.swatch{
appearance:none;border:0;cursor:pointer;
width:26px;height:26px;border-radius:999px;
box-shadow:0 0 0 1px rgba(255,255,255,.12),0 6px 14px rgba(0,0,0,.35);
}
.swatch[data-metal="gold"]{background:linear-gradient(145deg,#e8d090,#b8903c 55%,#8f6f2e)}
.swatch[data-metal="silver"]{background:linear-gradient(145deg,#e8eaee,#9aa0a8 55%,#6a6e74)}
.swatch.is-on{box-shadow:0 0 0 2px #ececee,0 0 0 4px rgba(230,255,85,.55),0 6px 14px rgba(0,0,0,.35)}
.hint{
flex-shrink:0;font-family:var(--mono);font-size:10px;
letter-spacing:.16em;text-transform:uppercase;color:#6a6660;pointer-events:none;
}
.stage{
perspective:1100px;perspective-origin:50% 45%;
width:min(520px,92vw,calc((100dvh - 7.25rem)*1.586));max-width:100%;
}
.card{
position:relative;width:100%;aspect-ratio:1.586/1;border-radius:16px;
overflow:hidden;isolation:isolate;
transform:rotateX(var(--rx)) rotateY(var(--ry));
transform-style:preserve-3d;will-change:transform;
background:var(--plate);box-shadow:var(--rim);
}
.card[data-metal="gold"]{
--plate:linear-gradient(145deg,#8f6f2e 0%,#c9a84a 18%,#e8d090 36%,#b8903c 52%,#f2dfaa 64%,#a57f32 82%,#7a5c24 100%);
--rim:0 0 0 1.5px #c9a84a,0 0 0 2.5px #2a2110,inset 0 1px 0 rgba(255,245,210,.55),inset 0 -1px 0 rgba(60,40,10,.35),0 28px 55px -20px rgba(0,0,0,.75);
}
.card[data-metal="silver"]{
--plate:linear-gradient(145deg,#6a6e74 0%,#b8bcc2 18%,#e4e6ea 36%,#9aa0a8 52%,#f2f3f5 64%,#8a9098 82%,#555a62 100%);
--rim:0 0 0 1.5px #c8ccd2,0 0 0 2.5px #1c1e22,inset 0 1px 0 rgba(255,255,255,.55),inset 0 -1px 0 rgba(30,32,36,.35),0 28px 55px -20px rgba(0,0,0,.75);
}
.card[data-metal="silver"] .chip-body{fill:url(#cs);stroke:#5a5e66}
.card[data-metal="silver"] .chip-pads{fill:url(#cps)}
.gl{
position:absolute;inset:0;width:100%;height:100%;display:block;
z-index:2;pointer-events:none;mix-blend-mode:overlay;opacity:.38;
}
.guilloche{
position:absolute;inset:0;pointer-events:none;opacity:.28;z-index:1;
background-image:
repeating-radial-gradient(circle at 20% 30%,transparent 0 6px,rgba(40,28,8,.35) 6px 7px),
repeating-radial-gradient(circle at 80% 70%,transparent 0 8px,rgba(255,240,190,.2) 8px 9px),
repeating-linear-gradient(0deg,transparent 0 3px,rgba(60,40,12,.12) 3px 4px),
repeating-linear-gradient(90deg,transparent 0 5px,rgba(255,245,210,.08) 5px 6px);
mix-blend-mode:multiply;
}
.card[data-metal="silver"] .guilloche{
background-image:
repeating-radial-gradient(circle at 20% 30%,transparent 0 6px,rgba(20,22,26,.35) 6px 7px),
repeating-radial-gradient(circle at 80% 70%,transparent 0 8px,rgba(255,255,255,.18) 8px 9px),
repeating-linear-gradient(0deg,transparent 0 3px,rgba(30,32,36,.12) 3px 4px),
repeating-linear-gradient(90deg,transparent 0 5px,rgba(255,255,255,.08) 5px 6px);
}
.brush{
position:absolute;inset:0;pointer-events:none;opacity:.4;z-index:1;
background:repeating-linear-gradient(90deg,transparent 0 1px,rgba(255,248,220,.06) 1px 2px,transparent 2px 4px);
}
.card[data-metal="silver"] .brush{
background:repeating-linear-gradient(90deg,transparent 0 1px,rgba(255,255,255,.07) 1px 2px,transparent 2px 4px);
}
.vignette{
position:absolute;inset:0;pointer-events:none;z-index:1;
background:radial-gradient(80% 70% at 50% 40%,transparent 35%,rgba(50,35,10,.22) 100%);
}
.card[data-metal="silver"] .vignette{
background:radial-gradient(80% 70% at 50% 40%,transparent 35%,rgba(20,22,26,.22) 100%);
}
.frame{
position:absolute;inset:10px;border-radius:8px;pointer-events:none;z-index:3;
border:1px solid rgba(25,18,8,.35);
box-shadow:inset 0 0 0 1px rgba(255,240,190,.18),0 0 0 1px rgba(255,240,190,.1);
}
.card[data-metal="silver"] .frame{
border-color:rgba(18,20,24,.4);
box-shadow:inset 0 0 0 1px rgba(255,255,255,.16),0 0 0 1px rgba(255,255,255,.08);
}
.frame::before{
content:"";position:absolute;inset:3px;border-radius:5px;
border:1px solid rgba(30,20,8,.2);opacity:.7;
}
.content{
position:relative;z-index:4;height:100%;
display:grid;grid-template-rows:auto 1fr auto;
padding:clamp(14px,4.4vw,26px) clamp(16px,4.8vw,28px) clamp(12px,3.8vw,22px);
}
.foil{
color:rgba(48,34,14,.42);
text-shadow:0 .5px 0 rgba(255,248,220,.38),0 -.5px 0 rgba(28,18,6,.16);
}
.foil span{
color:rgba(176,52,28,.62);
text-shadow:0 .5px 0 rgba(255,248,220,.28),0 -.5px 0 rgba(80,18,10,.18);
}
.card[data-metal="silver"] .foil{
color:rgba(28,32,38,.4);
text-shadow:0 .5px 0 rgba(255,255,255,.4),0 -.5px 0 rgba(12,14,18,.16);
}
.imp{
color:rgba(28,20,8,.55);
text-shadow:0 .5px 0 rgba(255,245,210,.32),0 -.5px 0 rgba(16,10,4,.18);
}
.imp-soft{
color:rgba(32,22,10,.38);
text-shadow:0 .5px 0 rgba(255,245,210,.22),0 -.5px 0 rgba(18,12,6,.12);
}
.imp-deep{
color:rgba(22,16,8,.62);
text-shadow:0 .75px 0 rgba(255,248,220,.36),0 -.5px 0 rgba(12,8,4,.22);
}
.card[data-metal="silver"] .imp{
color:rgba(22,24,28,.55);
text-shadow:0 .5px 0 rgba(255,255,255,.32),0 -.5px 0 rgba(10,12,14,.18);
}
.card[data-metal="silver"] .imp-soft{
color:rgba(26,28,32,.4);
text-shadow:0 .5px 0 rgba(255,255,255,.22),0 -.5px 0 rgba(12,14,16,.12);
}
.card[data-metal="silver"] .imp-deep{
color:rgba(16,18,22,.62);
text-shadow:0 .75px 0 rgba(255,255,255,.36),0 -.5px 0 rgba(8,10,12,.22);
}
.head{display:flex;align-items:flex-start;justify-content:space-between}
.brand{display:flex;align-items:center;gap:10px}
.mark{
width:32px;height:32px;border-radius:8px;display:grid;place-items:center;
font-family:var(--display);font-weight:700;font-size:14px;letter-spacing:-.05em;
color:rgba(48,34,14,.5);background:transparent;
box-shadow:inset 0 0 0 .5px rgba(28,18,6,.18),0 .5px 0 rgba(255,248,220,.28);
text-shadow:0 .5px 0 rgba(255,248,220,.32),0 -.5px 0 rgba(28,18,6,.14);
}
.card[data-metal="silver"] .mark{
color:rgba(28,32,38,.48);
box-shadow:inset 0 0 0 .5px rgba(12,14,18,.18),0 .5px 0 rgba(255,255,255,.28);
text-shadow:0 .5px 0 rgba(255,255,255,.32),0 -.5px 0 rgba(12,14,18,.14);
}
.word{font-family:var(--display);font-size:clamp(16px,4.2vw,19px);font-weight:650;letter-spacing:-.02em}
.sub{margin-top:4px;font-family:var(--mono);font-size:8px;letter-spacing:.2em;text-transform:uppercase;font-weight:500}
.waves{margin-top:2px;opacity:.7}
.waves svg{display:block;width:24px;height:15px}
.mid{display:flex;align-items:center;gap:clamp(12px,3vw,18px);align-self:center}
.chip{width:clamp(40px,9vw,50px);height:auto;flex-shrink:0;filter:drop-shadow(0 1px 1px rgba(40,25,8,.28))}
.pan{font-family:var(--mono);font-size:clamp(12px,3.2vw,16px);font-weight:500;letter-spacing:.24em}
.foot{display:flex;align-items:flex-end;justify-content:space-between;gap:12px}
.label{font-family:var(--mono);font-size:7.5px;font-weight:500;letter-spacing:.2em;text-transform:uppercase}
.value{margin-top:6px;font-family:var(--display);font-size:clamp(11px,3vw,13px);font-weight:600;letter-spacing:.1em}
.member{text-align:right}
.member .yr{margin-top:5px;font-family:var(--mono);font-size:13px;font-weight:500;letter-spacing:.14em}
.url{
position:absolute;right:clamp(16px,4.8vw,28px);top:50%;
transform:translateY(-50%) rotate(180deg);writing-mode:vertical-rl;
font-family:var(--mono);font-size:8px;font-weight:500;letter-spacing:.22em;text-transform:uppercase;opacity:.5;
}
@media (prefers-reduced-motion:reduce){
.card{transform:none}
.gl{display:none}
}
`;
 
const VERT = "attribute vec2 a;void main(){gl_Position=vec4(a,0.0,1.0);}";
 
const FRAG = `
precision highp float;
uniform vec2 uRes;
uniform vec2 uMouse;
uniform float uTime;
uniform float uShine;
float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453123);}
float noise(vec2 p){
vec2 i=floor(p);vec2 f=fract(p);
float a=hash(i),b=hash(i+vec2(1.0,0.0)),c=hash(i+vec2(0.0,1.0)),d=hash(i+vec2(1.0,1.0));
vec2 u=f*f*(3.0-2.0*f);
return mix(a,b,u.x)+(c-a)*u.y*(1.0-u.x)+(d-b)*u.x*u.y;
}
void main(){
vec2 uv=gl_FragCoord.xy/uRes;
float brush=noise(vec2(uv.x*120.0,uv.y*14.0+uTime*0.04));
float grain=noise(uv*vec2(280.0,220.0)+uTime*0.08);
float sweep=sin(uv.x*8.0+uv.y*1.6+uTime*0.28+brush*3.0)*0.5+0.5;
float spec=pow(max(0.0,1.0-length((uv-uMouse)*vec2(1.2,1.55))*1.7),3.2);
float light=0.42+brush*0.22+sweep*0.12+(grain-0.5)*0.10;
light+=spec*(0.22+0.55*uShine);
gl_FragColor=vec4(vec3(light),1.0);
}
`;
 
const SCRIPT = `
(function () {
var card = document.getElementById("card");
var stage = document.getElementById("stage");
var canvas = document.getElementById("gl");
if (!card || !stage) return;
 
var reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
var mx = 0.48, my = 0.38, shine = 0;
var glState = null;
 
function onMove(e) {
var r = stage.getBoundingClientRect();
var nx = (e.clientX - r.left) / r.width;
var ny = (e.clientY - r.top) / r.height;
mx = nx; my = ny; shine = reduced ? 0.35 : 1;
if (!reduced) {
card.style.setProperty("--ry", ((nx - 0.5) * 10).toFixed(2) + "deg");
card.style.setProperty("--rx", ((0.5 - ny) * 7).toFixed(2) + "deg");
}
if (glState) glState.setPointer(nx, ny, shine);
}
function onLeave() {
mx = 0.48; my = 0.38; shine = 0;
card.style.setProperty("--ry", "0deg");
card.style.setProperty("--rx", "0deg");
if (glState) glState.setPointer(mx, my, 0);
}
stage.addEventListener("pointermove", onMove);
stage.addEventListener("pointerenter", onMove);
stage.addEventListener("pointerleave", onLeave);
 
function setMetal(name) {
if (name !== "gold" && name !== "silver") return;
card.setAttribute("data-metal", name);
document.querySelectorAll(".swatch").forEach(function (btn) {
btn.classList.toggle("is-on", btn.getAttribute("data-metal") === name);
});
try {
var url = new URL(window.location.href);
url.searchParams.set("metal", name);
history.replaceState(null, "", url);
} catch (err) {}
}
document.querySelectorAll(".swatch").forEach(function (btn) {
btn.addEventListener("click", function () {
setMetal(btn.getAttribute("data-metal"));
});
});
 
function compile(gl, type, src) {
var shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
gl.deleteShader(shader);
return null;
}
return shader;
}
 
function startGL() {
if (!canvas || reduced) return null;
var gl = canvas.getContext("webgl", { alpha: false, antialias: false, powerPreference: "low-power" });
if (!gl) return null;
var vs = compile(gl, gl.VERTEX_SHADER, ${JSON.stringify(VERT)});
var fs = compile(gl, gl.FRAGMENT_SHADER, ${JSON.stringify(FRAG)});
if (!vs || !fs) return null;
var program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) return null;
gl.useProgram(program);
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,-1, 1,-1, -1,1, 1,1]), gl.STATIC_DRAW);
var loc = gl.getAttribLocation(program, "a");
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
var uRes = gl.getUniformLocation(program, "uRes");
var uMouse = gl.getUniformLocation(program, "uMouse");
var uTime = gl.getUniformLocation(program, "uTime");
var uShine = gl.getUniformLocation(program, "uShine");
var t0 = performance.now();
var pointer = { x: mx, y: my, shine: shine };
 
function resize() {
var box = canvas.getBoundingClientRect();
var dpr = Math.min(2, window.devicePixelRatio || 1);
var w = Math.max(2, Math.floor(box.width * dpr));
var h = Math.max(2, Math.floor(box.height * dpr));
if (canvas.width !== w || canvas.height !== h) {
canvas.width = w;
canvas.height = h;
gl.viewport(0, 0, w, h);
}
}
function frame(now) {
resize();
gl.uniform2f(uRes, canvas.width, canvas.height);
gl.uniform2f(uMouse, pointer.x, 1 - pointer.y);
gl.uniform1f(uTime, (now - t0) / 1000);
gl.uniform1f(uShine, pointer.shine);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
return {
setPointer: function (x, y, s) {
pointer.x = x; pointer.y = y; pointer.shine = s;
}
};
}
 
glState = startGL();
})();
`;
 
function page(metal) {
const goldOn = metal === "gold" ? " is-on" : "";
const silverOn = metal === "silver" ? " is-on" : "";
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>QuikRun · ${NAME}</title>
<meta name="description" content="Luxury QuikRun metal card for ${NAME}." />
<meta property="og:title" content="QuikRun · ${NAME}" />
<meta property="og:url" content="${LIVE}" />
<meta property="og:image" content="${OG}" />
<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=IBM+Plex+Mono:wght@400;500&family=Outfit:wght@500;600;700;800&display=swap" rel="stylesheet" />
<style>${CSS}</style>
</head>
<body>
<div class="wrap">
<div class="picker" role="group" aria-label="Metal finish">
<button class="swatch${goldOn}" data-metal="gold" type="button" title="Gold" aria-label="Gold"></button>
<button class="swatch${silverOn}" data-metal="silver" type="button" title="Silver" aria-label="Silver"></button>
</div>
<div class="stage" id="stage">
<article class="card" id="card" data-metal="${metal}">
<div class="guilloche" aria-hidden="true"></div>
<div class="brush" aria-hidden="true"></div>
<div class="vignette" aria-hidden="true"></div>
<canvas class="gl" id="gl"></canvas>
<div class="frame" aria-hidden="true"></div>
<div class="content">
<header class="head">
<div class="brand">
<div class="mark">q.</div>
<div>
<div class="word foil">QuikRun<span>.</span></div>
<div class="sub imp-soft">AI Code Runtime</div>
</div>
</div>
<div class="waves" aria-hidden="true">
<svg width="28" height="18" viewBox="0 0 28 18" fill="none">
<path d="M8 14a6 6 0 0 1 0-10" stroke="currentColor" stroke-opacity=".55" stroke-width="1.5" stroke-linecap="round"/>
<path d="M12 16a9 9 0 0 1 0-14" stroke="currentColor" stroke-opacity=".4" stroke-width="1.5" stroke-linecap="round"/>
<path d="M16 17.5a11.5 11.5 0 0 1 0-17" stroke="currentColor" stroke-opacity=".28" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</div>
</header>
<div class="mid">
${CHIP}
<div class="pan imp-deep">QR · 2026 · LIVE · EDGE</div>
</div>
<footer class="foot">
<div>
<div class="label imp-soft">Cardholder</div>
<div class="value imp">${NAME}</div>
</div>
<div class="member">
<div class="label imp-soft">Member Since</div>
<div class="yr imp">24</div>
</div>
</footer>
<div class="url imp-soft">quik.run</div>
</div>
</article>
</div>
<div class="hint">Move to tilt · pick a metal</div>
</div>
<script>${SCRIPT}</script>
</body>
</html>`;
}
 
export default async function handler(req) {
const q = (req && req.query) || {};
const metal = q.metal === "silver" ? "silver" : "gold";
return new Response(page(metal), {
status: 200,
headers: { "content-type": "text/html; charset=utf-8" },
});
}
 
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