Convert the Y2K theme from a Go+templ wasm plugin to a fully codeless .bnp: blocks/blocks.yaml + .ninjatpl, page/system templates, template overrides, email wrapper, master pages and CSS declared in manifest.yaml. All *.go, *.templ, *_templ.go, go.mod and go.sum deleted; schemas moved schemas/ -> blocks/. Static parity proven 48/48 identical against the templ baseline (10 blocks x full+empty+variant branches, 4 overrides incl. heading L1-6, email full+empty). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
265 lines
7.9 KiB
YAML
265 lines
7.9 KiB
YAML
# Y2K theme — codeless .bnp manifest (WO-WZ-021 Phase B).
|
|
# Synthesized into manifest.pb by `ninja plugin build` (no plugin.wasm).
|
|
theme_presets: presets.json
|
|
bundled_fonts: fonts.json
|
|
master_pages: master_pages.json
|
|
|
|
system_templates:
|
|
- key: y2k
|
|
title: Y2K
|
|
description: "Liquid-chrome Y2K revival theme for indie musicians, zines, and merch shops."
|
|
|
|
page_templates:
|
|
- system: y2k
|
|
key: default
|
|
title: Default
|
|
description: "Chrome navbar + content + footer."
|
|
slots: [header, main, footer]
|
|
- system: y2k
|
|
key: landing
|
|
title: Landing
|
|
description: "Hero metaball + marquee + CTAs."
|
|
slots: [hero, marquee, main, cta, footer]
|
|
- system: y2k
|
|
key: article
|
|
title: Article / Zine Page
|
|
description: "Narrow column with sidebar tracklist."
|
|
slots: [header, main, aside, footer]
|
|
- system: y2k
|
|
key: full-width
|
|
title: Full Width
|
|
description: "Edge-to-edge gradient mesh canvas."
|
|
slots: [header, main, footer]
|
|
|
|
template_overrides:
|
|
- { template: y2k, block: heading }
|
|
- { template: y2k, block: text }
|
|
- { template: y2k, block: button }
|
|
- { template: y2k, block: image }
|
|
|
|
email_wrappers:
|
|
- y2k
|
|
|
|
css:
|
|
input_css_append: |
|
|
/* === 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;
|
|
}
|
|
}
|