feat: binary micro-interactions across the page
Section headlines are written out behind a column of digits, mono labels resolve from binary, the portrait assembles itself from bits, section indexes rattle and keep one bit alive, cards get corner marks, the header shows the scroll position as an eight-bit number, pressed links and buttons shed a few digits, and the work stage leans towards the pointer. All effects respect reduced motion and leave the content readable without JavaScript. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1004,3 +1004,87 @@ pre:has(code[class*="language-"]) {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Binary micro-interactions ─────────────────────────────────────────────── */
|
||||
|
||||
/* Digits that fly out from a pressed link or button (see BitBurst). */
|
||||
.bit-burst {
|
||||
position: fixed;
|
||||
z-index: 200;
|
||||
pointer-events: none;
|
||||
/* On the layer, not the digits: a fixed layer blends as a whole with the page. */
|
||||
mix-blend-mode: difference;
|
||||
}
|
||||
.bit-burst span {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
font-family: var(--font-jetbrains-mono), ui-monospace, monospace;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
opacity: 0;
|
||||
animation: bit-burst-fly 620ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
@keyframes bit-burst-fly {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy)))
|
||||
scale(0.6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Corner marks that snap onto a card on hover or focus. */
|
||||
.bit-card {
|
||||
position: relative;
|
||||
}
|
||||
.bit-card::before,
|
||||
.bit-card::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border: 1.5px solid currentColor;
|
||||
opacity: 0;
|
||||
transition:
|
||||
opacity 250ms ease,
|
||||
transform 350ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
pointer-events: none;
|
||||
}
|
||||
.bit-card::before {
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
border-left: 0;
|
||||
border-bottom: 0;
|
||||
transform: translate(-6px, 6px);
|
||||
}
|
||||
.bit-card::after {
|
||||
bottom: 12px;
|
||||
left: 12px;
|
||||
border-right: 0;
|
||||
border-top: 0;
|
||||
transform: translate(6px, -6px);
|
||||
}
|
||||
.bit-card:hover::before,
|
||||
.bit-card:hover::after,
|
||||
.bit-card:focus-visible::before,
|
||||
.bit-card:focus-visible::after,
|
||||
.bit-card[aria-selected="true"]::before,
|
||||
.bit-card[aria-selected="true"]::after {
|
||||
opacity: 0.55;
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.bit-burst {
|
||||
display: none;
|
||||
}
|
||||
.bit-card::before,
|
||||
.bit-card::after {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Inter, JetBrains_Mono, Newsreader } from "next/font/google";
|
||||
import { Analytics } from "@/src/components/Analytics";
|
||||
import { BitBurst } from "@/src/components/bits/BitBurst";
|
||||
import { Footer } from "@/src/components/Footer";
|
||||
import { Header } from "@/src/components/Header";
|
||||
import { InteractiveElements } from "@/src/components/InteractiveElements";
|
||||
@@ -70,6 +71,7 @@ export default function RootLayout({
|
||||
<main>{children}</main>
|
||||
<Footer />
|
||||
<InteractiveElements />
|
||||
<BitBurst />
|
||||
<Analytics />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Metadata } from "next";
|
||||
import { DecodeText } from "@/src/components/bits/DecodeText";
|
||||
import { Block } from "@/src/components/home/Block";
|
||||
import { ClosingCta } from "@/src/components/home/ClosingCta";
|
||||
import { Faq } from "@/src/components/home/Faq";
|
||||
@@ -218,7 +219,7 @@ export default function LandingPage() {
|
||||
key={item}
|
||||
className="rounded-full border border-slate-200 bg-white px-4 py-2 font-mono text-[11px] uppercase tracking-[0.12em] text-slate-700"
|
||||
>
|
||||
{item}
|
||||
<DecodeText text={item} trigger="both" />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user