Files
vibn-frontend/design-templates/VIBN (2)/crossed.jsx

135 lines
4.0 KiB
JavaScript

// Crossed-out list — technical terms struck through, ending in "Your AI handles
// all of it. You just keep building."
const CROSSED_TERMS = [
"Databases",
"Auth providers",
"GitHub",
"Hosting",
"API keys",
"Environment variables",
"Deployment",
"Backend code",
"Servers",
"DNS records",
"SSL certificates",
"CORS errors",
"Webhooks",
"Build pipelines",
"package.json",
"npm install",
];
function CrossedOut() {
return (
<section className="section crossed">
<style>{`
.crossed { padding-block: clamp(70px, 10vh, 130px); }
.crossed-head { text-align: center; max-width: 760px; margin: 0 auto 56px; }
.crossed-title {
font-size: clamp(36px, 4.8vw, 64px);
font-weight: 500; letter-spacing: -0.025em; line-height: 1.02;
text-wrap: balance;
}
.crossed-sub {
margin-top: 18px;
color: var(--fg-mute);
font-size: 17px;
}
.crossed-wall {
display: flex; flex-wrap: wrap; gap: 10px 14px;
justify-content: center;
max-width: 880px; margin: 0 auto;
}
.crossed-item {
position: relative;
font-family: var(--font-mono);
font-size: clamp(15px, 1.7vw, 22px);
font-weight: 400;
color: var(--fg-mute);
padding: 8px 14px;
border-radius: 8px;
background: oklch(0.20 0.009 60 / 0.45);
border: 1px solid var(--hairline);
letter-spacing: 0.005em;
overflow: hidden;
}
.crossed-item::after {
content: "";
position: absolute;
left: 8px; right: 8px;
top: 50%;
height: 2px;
transform: translateY(-50%) rotate(-1deg);
background: var(--accent);
box-shadow: 0 0 12px var(--accent-glow);
border-radius: 2px;
opacity: 0;
animation: strike 0.6s cubic-bezier(.7,.1,.3,1) forwards;
animation-delay: var(--delay, 0s);
}
.crossed-item .term {
opacity: 1;
animation: fade 0.4s ease forwards;
animation-delay: var(--delay, 0s);
display: inline-block;
}
@keyframes strike {
from { opacity: 0; transform: translateY(-50%) rotate(-1deg) scaleX(0); transform-origin: left center; }
to { opacity: 1; transform: translateY(-50%) rotate(-1deg) scaleX(1); transform-origin: left center; }
}
@keyframes fade {
to { opacity: 0.5; }
}
.crossed-closer {
margin-top: 56px;
text-align: center;
font-size: clamp(24px, 3vw, 36px);
font-weight: 500; letter-spacing: -0.02em;
line-height: 1.18;
text-wrap: balance;
max-width: 760px; margin-inline: auto; margin-top: 56px;
}
.crossed-closer .accent { color: var(--accent); }
.crossed-closer .sep {
display: block; width: 48px; height: 1px;
background: var(--hairline);
margin: 28px auto;
}
`}</style>
<div className="wrap">
<div className="crossed-head">
<Eyebrow>What you don't have to learn</Eyebrow>
<h2 className="crossed-title" style={{ marginTop: 18 }}>
All the stuff that made you give up last time.
</h2>
<p className="crossed-sub">Forget every word on this list.</p>
</div>
<div className="crossed-wall">
{CROSSED_TERMS.map((term, i) => (
<span
className="crossed-item"
key={term}
style={{ "--delay": `${0.12 + i * 0.06}s` }}
>
<span className="term">{term}</span>
</span>
))}
</div>
<p className="crossed-closer">
Your AI handles <span className="accent">all of it</span>.
<span className="sep" />
You just keep building.
</p>
</div>
</section>
);
}
Object.assign(window, { CrossedOut });