Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/y2k. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
229 lines
6.2 KiB
Go
229 lines
6.2 KiB
Go
package main
|
|
|
|
// y2kInputCSS is appended to the host Tailwind input. It declares the chrome
|
|
// gradient stops, mesh anchors, bevel shadows, marquee/sparkle/metaball
|
|
// keyframes, and the utility classes those keyframes drive. Every colour is
|
|
// expressed through theme HSL custom properties (no hardcoded hex/rgb).
|
|
const y2kInputCSS = `
|
|
/* === y2k theme — chrome/bevel/mesh tokens === */
|
|
:root {
|
|
--chrome-1: 280 30% 95%;
|
|
--chrome-2: 200 40% 75%;
|
|
--chrome-3: 320 60% 60%;
|
|
--chrome-4: 280 40% 25%;
|
|
--mesh-a: 320 95% 58%;
|
|
--mesh-b: 185 90% 60%;
|
|
--mesh-c: 60 95% 70%;
|
|
--bevel-light: 0 0% 100%;
|
|
--bevel-dark: 280 60% 12%;
|
|
}
|
|
.dark {
|
|
--chrome-1: 280 30% 30%;
|
|
--chrome-2: 200 40% 45%;
|
|
--chrome-3: 320 60% 50%;
|
|
--chrome-4: 280 40% 10%;
|
|
--mesh-a: 320 100% 65%;
|
|
--mesh-b: 185 95% 55%;
|
|
--mesh-c: 60 100% 65%;
|
|
--bevel-light: 0 0% 100%;
|
|
--bevel-dark: 280 80% 4%;
|
|
}
|
|
|
|
/* === keyframes === */
|
|
@keyframes marquee-x {
|
|
from { transform: translate3d(0, 0, 0); }
|
|
to { transform: translate3d(-50%, 0, 0); }
|
|
}
|
|
@keyframes sparkle {
|
|
0%, 100% { opacity: 0; transform: scale(0.5) rotate(0deg); }
|
|
50% { opacity: 1; transform: scale(1) rotate(180deg); }
|
|
}
|
|
@keyframes metaball-morph {
|
|
0%, 100% { d: path("M 50 100 a 50 50 0 1 1 100 0 a 50 50 0 1 1 -100 0"); }
|
|
50% { d: path("M 40 95 a 60 55 0 1 1 120 5 a 55 60 0 1 1 -120 -5"); }
|
|
}
|
|
|
|
/* === chrome surface utilities === */
|
|
.y2k-chrome-bg {
|
|
background-image:
|
|
linear-gradient(180deg,
|
|
hsl(var(--chrome-1)) 0%,
|
|
hsl(var(--chrome-2)) 35%,
|
|
hsl(var(--chrome-3)) 70%,
|
|
hsl(var(--chrome-4)) 100%);
|
|
}
|
|
.y2k-mesh-bg {
|
|
background-image:
|
|
radial-gradient(at 20% 20%, hsl(var(--mesh-a) / 0.85) 0%, transparent 55%),
|
|
radial-gradient(at 80% 30%, hsl(var(--mesh-b) / 0.80) 0%, transparent 55%),
|
|
radial-gradient(at 50% 80%, hsl(var(--mesh-c) / 0.70) 0%, transparent 55%),
|
|
linear-gradient(135deg, hsl(var(--background)) 0%, hsl(var(--card)) 100%);
|
|
}
|
|
.y2k-bevel {
|
|
border: 2px solid hsl(var(--border));
|
|
box-shadow:
|
|
inset 0 1px 0 hsl(var(--bevel-light) / 0.85),
|
|
inset 0 -2px 0 hsl(var(--bevel-dark) / 0.35),
|
|
0 2px 6px hsl(var(--bevel-dark) / 0.30);
|
|
}
|
|
.y2k-bevel:active {
|
|
box-shadow:
|
|
inset 0 2px 4px hsl(var(--bevel-dark) / 0.45),
|
|
inset 0 -1px 0 hsl(var(--bevel-light) / 0.40);
|
|
}
|
|
.y2k-glow {
|
|
box-shadow: 0 0 24px hsl(var(--primary) / 0.45);
|
|
}
|
|
|
|
/* === marquee === */
|
|
.y2k-marquee {
|
|
overflow: hidden;
|
|
position: relative;
|
|
border-top: 2px solid hsl(var(--border));
|
|
border-bottom: 2px solid hsl(var(--border));
|
|
}
|
|
.y2k-marquee-track {
|
|
display: inline-flex;
|
|
gap: 3rem;
|
|
white-space: nowrap;
|
|
animation-name: marquee-x;
|
|
animation-timing-function: linear;
|
|
animation-iteration-count: infinite;
|
|
}
|
|
.y2k-marquee-track[data-speed="slow"] { animation-duration: 60s; }
|
|
.y2k-marquee-track[data-speed="medium"] { animation-duration: 30s; }
|
|
.y2k-marquee-track[data-speed="fast"] { animation-duration: 12s; }
|
|
.y2k-marquee:hover .y2k-marquee-track,
|
|
.y2k-marquee:focus-within .y2k-marquee-track {
|
|
animation-play-state: paused;
|
|
}
|
|
|
|
/* === sparkle decoration === */
|
|
.y2k-sparkle {
|
|
pointer-events: none;
|
|
animation: sparkle 1.6s ease-in-out infinite;
|
|
}
|
|
|
|
/* === metaball morph === */
|
|
.y2k-metaball {
|
|
animation: metaball-morph 6s ease-in-out infinite;
|
|
}
|
|
|
|
/* === webring 88x31 badge === */
|
|
.y2k-webring-badge {
|
|
display: inline-block;
|
|
width: 88px;
|
|
height: 31px;
|
|
line-height: 31px;
|
|
text-align: center;
|
|
font-size: 11px;
|
|
letter-spacing: 0.05em;
|
|
text-transform: uppercase;
|
|
border: 1px solid hsl(var(--border));
|
|
background-image: linear-gradient(180deg, hsl(var(--chrome-1)) 0%, hsl(var(--chrome-3)) 100%);
|
|
color: hsl(var(--primaryForeground));
|
|
text-decoration: none;
|
|
box-shadow: inset 0 1px 0 hsl(var(--bevel-light) / 0.6);
|
|
}
|
|
|
|
/* === holographic foil for NFT gallery === */
|
|
.y2k-foil {
|
|
position: relative;
|
|
isolation: isolate;
|
|
}
|
|
.y2k-foil::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
transition: opacity 220ms ease;
|
|
background-image: conic-gradient(
|
|
from 0deg,
|
|
hsl(var(--mesh-a) / 0.45),
|
|
hsl(var(--mesh-b) / 0.45),
|
|
hsl(var(--mesh-c) / 0.45),
|
|
hsl(var(--mesh-a) / 0.45)
|
|
);
|
|
mix-blend-mode: color-dodge;
|
|
filter: hue-rotate(0deg);
|
|
}
|
|
.y2k-foil:hover::after,
|
|
.y2k-foil:focus-within::after {
|
|
opacity: 1;
|
|
filter: hue-rotate(45deg);
|
|
}
|
|
|
|
/* === plastic button override === */
|
|
.y2k-button {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.65rem 1.25rem;
|
|
font-weight: 600;
|
|
border: 2px solid hsl(var(--border));
|
|
border-radius: 0.625rem;
|
|
background-image: linear-gradient(180deg,
|
|
hsl(var(--primary) / 0.95) 0%,
|
|
hsl(var(--primary)) 50%,
|
|
hsl(var(--primary) / 0.85) 100%);
|
|
color: hsl(var(--primaryForeground));
|
|
box-shadow:
|
|
inset 0 1px 0 hsl(var(--bevel-light) / 0.7),
|
|
inset 0 -2px 0 hsl(var(--bevel-dark) / 0.3),
|
|
0 2px 6px hsl(var(--bevel-dark) / 0.25);
|
|
transition: transform 90ms ease, box-shadow 90ms ease;
|
|
}
|
|
.y2k-button:hover { transform: translateY(-1px); }
|
|
.y2k-button:active {
|
|
transform: translateY(1px);
|
|
box-shadow:
|
|
inset 0 2px 4px hsl(var(--bevel-dark) / 0.45),
|
|
inset 0 -1px 0 hsl(var(--bevel-light) / 0.30);
|
|
}
|
|
.y2k-button:focus-visible {
|
|
outline: 2px solid hsl(var(--ring));
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* === image chrome frame === */
|
|
.y2k-image-frame {
|
|
border-radius: 0.625rem;
|
|
border: 2px solid hsl(var(--border));
|
|
box-shadow:
|
|
inset 0 1px 0 hsl(var(--bevel-light) / 0.5),
|
|
0 4px 14px hsl(var(--bevel-dark) / 0.35);
|
|
}
|
|
|
|
/* === heading chrome stroke === */
|
|
.y2k-heading {
|
|
font-family: var(--font-heading, "Stretch Pro", "VT323", "Courier New", monospace);
|
|
letter-spacing: 0.04em;
|
|
text-shadow:
|
|
0 1px 0 hsl(var(--bevel-light) / 0.65),
|
|
0 2px 0 hsl(var(--bevel-dark) / 0.35),
|
|
0 6px 22px hsl(var(--primary) / 0.45);
|
|
}
|
|
|
|
/* === text holographic link underline === */
|
|
.y2k-text a {
|
|
background-image: linear-gradient(90deg,
|
|
hsl(var(--mesh-a)),
|
|
hsl(var(--mesh-b)),
|
|
hsl(var(--mesh-c)));
|
|
background-size: 100% 2px;
|
|
background-repeat: no-repeat;
|
|
background-position: 0 100%;
|
|
text-decoration: none;
|
|
}
|
|
|
|
/* === reduced motion overrides === */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.y2k-marquee-track,
|
|
.y2k-sparkle,
|
|
.y2k-metaball {
|
|
animation: none !important;
|
|
}
|
|
}
|
|
`
|