# Y2K theme — codeless .bnp manifest (WO-TF-026, Wave A). # Synthesized into manifest.pb by `ninja plugin build` (no plugin.wasm). # Persona: musician / band. Millennium-web nostalgia — liquid chrome, frosted # iMac plastic (light) and rave blacklight (dark), marquees, glitter, a webring, # and a dependency-free canvas metaball hero showpiece (hero/landing only). theme_presets: presets.json bundled_fonts: fonts.json master_pages: master_pages.json required_icon_packs: ["lucide", "simple-icons"] system_templates: - key: y2k title: Y2K description: "Millennium-web band theme — liquid-chrome bevels, frosted plastic, marquees, glitter, a webring, and a canvas metaball hero." page_templates: - system: y2k key: default title: Default description: "Chrome header, sparkle backdrop, plastic content column, chrome footer" slots: [header, main, footer] - system: y2k key: full-width title: Full Width description: "Edge-to-edge showcase layout with a mesh backdrop, no max-width" slots: [header, main, footer] - system: y2k key: landing title: Landing description: "Canvas metaball hero, chrome feature grid, glitter CTA, chrome footer" slots: [header, main, footer] - system: y2k key: article title: Article / Liner Notes description: "Prose column with a chrome sidebar aside — liner-notes layout" slots: [header, main, aside, footer] - system: y2k key: blog-index title: Blog Index description: "Zine feed of chrome post cards" slots: [header, main, footer] - system: y2k key: contact title: Contact description: "Chrome contact console — form panel plus a plastic contact card" slots: [header, main, footer] - system: y2k key: auth title: Auth description: "Centered chrome auth panel for login / register / reset" slots: [header, main, footer] # All 49 mandatory-tier builtin overrides (OVERRIDE-CONTRACT §1), dashed keys. template_overrides: # Chrome (4) - { template: y2k, block: navbar } - { template: y2k, block: footer } - { template: y2k, block: utility-bar } - { template: y2k, block: announcement-bar } # Marketing (12) - { template: y2k, block: hero } - { template: y2k, block: feature-grid } - { template: y2k, block: rich-section } - { template: y2k, block: stats } - { template: y2k, block: testimonial } - { template: y2k, block: logo-strip } - { template: y2k, block: pricing } - { template: y2k, block: team } - { template: y2k, block: faq } - { template: y2k, block: timeline } - { template: y2k, block: cta } - { template: y2k, block: countdown } # Primitives (11) - { template: y2k, block: heading } - { template: y2k, block: text } - { template: y2k, block: rich-text } - { template: y2k, block: image } - { template: y2k, block: quote } - { template: y2k, block: divider } - { template: y2k, block: button } - { template: y2k, block: card } - { template: y2k, block: gallery } - { template: y2k, block: video-embed } - { template: y2k, block: audio-embed } # Commerce / local (6) - { template: y2k, block: menu-list } - { template: y2k, block: event-list } - { template: y2k, block: contact-form } - { template: y2k, block: contact-card } - { template: y2k, block: hours-location } - { template: y2k, block: social-links } # Blog family (12) - { template: y2k, block: blog-hero } - { template: y2k, block: featured-posts } - { template: y2k, block: related-posts } - { template: y2k, block: popular-posts } - { template: y2k, block: category-list } - { template: y2k, block: post-hero } - { template: y2k, block: post-metadata } - { template: y2k, block: author-bio } - { template: y2k, block: author-bio-hero } - { template: y2k, block: newsletter-signup } - { template: y2k, block: breadcrumbs } - { template: y2k, block: sidebar-nav } # Auth surface (3) - { template: y2k, block: auth-form } - { template: y2k, block: password-reset-form } - { template: y2k, block: auth-status } # System (1) - { template: y2k, block: page-suggestions } email_wrappers: - y2k css: input_css_append: | /* ============================================================ Y2K — millennium-web band theme (WO-TF-026). Liquid chrome, frosted-plastic bevels, gradient mesh, marquee, glitter/sparkle, webring badge, and a canvas metaball hero. Light = frosted iMac plastic. Dark = rave blacklight. Every colour resolves through the host shadcn HSL tokens via hsl(var(--token)); the extra chrome/mesh/bevel custom properties below are HSL triples consumed the same way. No literal hex/rgb. ============================================================ */ /* --- Chrome / mesh / bevel channel tokens ----------------- */ :root { --chrome-1: 220 40% 96%; --chrome-2: 205 45% 82%; --chrome-3: 300 45% 78%; --chrome-4: 240 35% 55%; --mesh-a: 320 95% 62%; --mesh-b: 190 90% 60%; --mesh-c: 55 95% 68%; --bevel-light: 0 0% 100%; --bevel-dark: 250 45% 22%; } .dark { --chrome-1: 280 35% 24%; --chrome-2: 250 40% 18%; --chrome-3: 315 55% 30%; --chrome-4: 265 45% 10%; --mesh-a: 320 100% 66%; --mesh-b: 150 95% 58%; --mesh-c: 275 95% 66%; --bevel-light: 300 60% 78%; --bevel-dark: 270 80% 4%; } /* --- Keyframes -------------------------------------------- */ @keyframes y2k-marquee-x { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } } @keyframes y2k-sparkle { 0%, 100% { opacity: 0; transform: scale(0.4) rotate(0deg); } 50% { opacity: 1; transform: scale(1) rotate(180deg); } } @keyframes y2k-shimmer-sweep { 0% { background-position: -150% 0; } 100% { background-position: 250% 0; } } @keyframes y2k-blink { 0%, 50% { opacity: 1; } 51%, 100% { opacity: 0; } } @keyframes y2k-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.45; transform: scale(0.82); } } /* --- Typography ------------------------------------------- */ /* Families flow through the admin-bound CSS variables; the fallback leads with the bundled OFL family so the intended look survives before the admin assigns a slot. @font-face for the bundled families is auto-emitted from fonts.json (source=template rows). */ .y2k-body { font-family: var(--font-body, "Inter", system-ui, -apple-system, "Segoe UI", sans-serif); } .y2k-mono, .y2k-mono code, pre.y2k-mono, code.y2k-mono { font-family: var(--font-mono, "Share Tech Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, monospace); } .y2k-display { font-family: var(--font-heading, "Orbitron", "Michroma", system-ui, sans-serif); letter-spacing: 0.02em; } /* Beveled chrome headline — bright top rim, dark under-shadow, coloured halo. */ .y2k-heading, .glitch { font-family: var(--font-heading, "Orbitron", "Michroma", system-ui, sans-serif); letter-spacing: 0.03em; text-shadow: 0 1px 0 hsl(var(--bevel-light) / 0.7), 0 2px 0 hsl(var(--bevel-dark) / 0.35), 0 6px 22px hsl(var(--primary) / 0.4); } /* Chrome shimmer sweep across big headlines (motion, reduced-motion-safe). */ .glitch { position: relative; background-image: linear-gradient( 100deg, transparent 20%, hsl(var(--bevel-light) / 0.65) 45%, hsl(var(--accent) / 0.55) 50%, transparent 60%); background-size: 220% 100%; background-repeat: no-repeat; -webkit-background-clip: text; background-clip: text; animation: y2k-shimmer-sweep 5.5s ease-in-out infinite; } .y2k-prose, .y2k-prose p, .y2k-prose li { font-family: var(--font-body, "Inter", system-ui, sans-serif); line-height: 1.75; } .y2k-prose code { color: hsl(var(--primary)); background-color: hsl(var(--muted)); padding: 0.125rem 0.375rem; border-radius: 0.25rem; font-family: var(--font-mono, "Share Tech Mono", ui-monospace, monospace); font-size: 0.875em; } /* Eyebrow / kicker: mono, uppercase, wide-tracked chrome readout. */ .y2k-eyebrow { font-family: var(--font-mono, "Share Tech Mono", ui-monospace, monospace); text-transform: uppercase; letter-spacing: 0.22em; font-size: 0.75rem; color: hsl(var(--primary)); } /* --- Chrome surfaces / backdrops -------------------------- */ .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 18% 20%, hsl(var(--mesh-a) / 0.8) 0%, transparent 55%), radial-gradient(at 82% 28%, hsl(var(--mesh-b) / 0.75) 0%, transparent 55%), radial-gradient(at 50% 82%, hsl(var(--mesh-c) / 0.65) 0%, transparent 55%), linear-gradient(135deg, hsl(var(--background)) 0%, hsl(var(--card)) 100%); } /* Sticky header chrome bar. */ .y2k-chrome { background-image: linear-gradient(180deg, hsl(var(--chrome-1) / 0.92) 0%, hsl(var(--chrome-2) / 0.88) 100%); backdrop-filter: saturate(1.3) blur(6px); box-shadow: inset 0 1px 0 hsl(var(--bevel-light) / 0.7); } /* --- Bevel / frame / glow --------------------------------- */ .y2k-bevel, .hud-frame { position: relative; border: 2px solid hsl(var(--border)); box-shadow: inset 0 1px 0 hsl(var(--bevel-light) / 0.8), inset 0 -2px 0 hsl(var(--bevel-dark) / 0.3), 0 3px 10px hsl(var(--bevel-dark) / 0.28); } .y2k-image-frame { border-radius: 0.75rem; border: 2px solid hsl(var(--border)); box-shadow: inset 0 1px 0 hsl(var(--bevel-light) / 0.5), 0 4px 16px hsl(var(--bevel-dark) / 0.35); } .y2k-glow, .neon-edge-magenta { box-shadow: 0 0 0 1px hsl(var(--primary) / 0.4), 0 0 22px hsl(var(--primary) / 0.28); transition: box-shadow 180ms ease, transform 180ms ease; } .y2k-glow:hover, .y2k-glow:focus-within, .neon-edge-magenta:hover, .neon-edge-magenta:focus-within { box-shadow: 0 0 0 1px hsl(var(--primary) / 0.85), 0 0 32px hsl(var(--primary) / 0.48); transform: translateY(-2px); } .neon-edge-cyan { box-shadow: 0 0 0 1px hsl(var(--accent) / 0.4), 0 0 22px hsl(var(--accent) / 0.28); transition: box-shadow 180ms ease, transform 180ms ease; } .neon-edge-cyan:hover, .neon-edge-cyan:focus-within { box-shadow: 0 0 0 1px hsl(var(--accent) / 0.85), 0 0 32px hsl(var(--accent) / 0.48); transform: translateY(-2px); } .neon-edge-lime { box-shadow: 0 0 0 1px hsl(var(--ring) / 0.4), 0 0 22px hsl(var(--ring) / 0.28); transition: box-shadow 180ms ease, transform 180ms ease; } .neon-edge-lime:hover, .neon-edge-lime:focus-within { box-shadow: 0 0 0 1px hsl(var(--ring) / 0.85), 0 0 32px hsl(var(--ring) / 0.48); transform: translateY(-2px); } /* clip-cut renders as soft rounded plastic corners in Y2K. */ .clip-cut { border-radius: 0.75rem; } /* --- Buttons ---------------------------------------------- */ .y2k-button, .y2k-btn, .rgb-split { transition: transform 90ms ease, box-shadow 90ms ease, filter 90ms ease; } .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.75rem; background-image: linear-gradient(180deg, hsl(var(--primary) / 0.96) 0%, hsl(var(--primary)) 50%, hsl(var(--primary) / 0.82) 100%); color: hsl(var(--primary-foreground)); box-shadow: inset 0 1px 0 hsl(var(--bevel-light) / 0.7), inset 0 -2px 0 hsl(var(--bevel-dark) / 0.3), 0 2px 8px hsl(var(--bevel-dark) / 0.25); } .y2k-btn { border-radius: 0.75rem; } .y2k-button:hover, .y2k-btn:hover, .rgb-split:hover, .rgb-split:focus-visible { transform: translateY(-1px); filter: brightness(1.05); } .y2k-button:active, .y2k-btn:active, .rgb-split:active { transform: translateY(1px); box-shadow: inset 0 2px 5px hsl(var(--bevel-dark) / 0.45), inset 0 -1px 0 hsl(var(--bevel-light) / 0.3); } .y2k-button:focus-visible, .y2k-btn:focus-visible, .rgb-split:focus-visible, button:focus-visible, a:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; } /* --- Cards ------------------------------------------------ */ .y2k-card { border-radius: 0.75rem; box-shadow: inset 0 1px 0 hsl(var(--bevel-light) / 0.55), 0 4px 14px hsl(var(--bevel-dark) / 0.22); } /* --- 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: y2k-marquee-x; animation-timing-function: linear; animation-iteration-count: infinite; animation-duration: 28s; } .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 / glitter atmosphere ------------------------- */ .y2k-sparkle { pointer-events: none; animation: y2k-sparkle 1.6s ease-in-out infinite; } /* scanlines (ported name) is repurposed as a faint glitter dot field. */ .scanlines { opacity: 0.4; background-image: radial-gradient(hsl(var(--primary) / 0.5) 1px, transparent 1.5px), radial-gradient(hsl(var(--accent) / 0.4) 1px, transparent 1.5px); background-size: 42px 42px, 68px 68px; background-position: 0 0, 24px 30px; } /* --- Status / caret -------------------------------------- */ .y2k-status-dot { animation: y2k-pulse 2.2s ease-in-out infinite; } .caret-blink { display: inline-block; animation: y2k-blink 1.05s steps(2, end) infinite; } /* --- Webring 88x31 badge ---------------------------------- */ .y2k-webring-badge { display: inline-flex; align-items: center; justify-content: center; width: 88px; height: 31px; 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(--primary-foreground)); text-decoration: none; box-shadow: inset 0 1px 0 hsl(var(--bevel-light) / 0.6); } /* --- Static waveform strip (no canvas — motion tier) ------ */ .y2k-waveform { background-image: repeating-linear-gradient( 90deg, hsl(var(--primary) / 0.65) 0 2px, hsl(var(--accent) / 0.4) 2px 4px, transparent 4px 8px); -webkit-mask-image: linear-gradient(90deg, transparent, hsl(0 0% 0%) 8%, hsl(0 0% 0%) 92%, transparent); mask-image: linear-gradient(90deg, transparent, hsl(0 0% 0%) 8%, hsl(0 0% 0%) 92%, transparent); border-radius: 0.25rem; } /* --- Empty state / article aside -------------------------- */ .y2k-empty { font-family: var(--font-mono, "Share Tech Mono", ui-monospace, monospace); letter-spacing: 0.14em; } .y2k-aside { border-radius: 0.75rem; } /* --- Canvas metaball showpiece (hero / landing only) ------ */ /* The lazy-inits from the hero's inline script; this styles the container plus the static no-JS chrome-mesh fallback. */ .y2k-orb-wrap { position: absolute; inset: 0; overflow: hidden; pointer-events: none; } .y2k-orb-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; opacity: 0.65; filter: blur(2px) contrast(1.15); } .y2k-orb-fallback { position: absolute; inset: 0; background-image: radial-gradient(60% 55% at 30% 35%, hsl(var(--mesh-a) / 0.55), transparent 60%), radial-gradient(55% 50% at 72% 45%, hsl(var(--mesh-b) / 0.5), transparent 60%), radial-gradient(50% 45% at 50% 80%, hsl(var(--mesh-c) / 0.45), transparent 60%), linear-gradient(to bottom, transparent, hsl(var(--background) / 0.7)); } /* --- Reduced motion: kill all motion ---------------------- */ @media (prefers-reduced-motion: reduce) { .y2k-marquee-track, .y2k-sparkle, .glitch, .caret-blink, .y2k-status-dot, .y2k-orb-canvas { animation: none !important; animation-duration: 0.01ms !important; } .glitch { background-image: none; -webkit-background-clip: border-box; background-clip: border-box; } .y2k-orb-canvas { display: none; } .y2k-button:hover, .y2k-btn:hover, .rgb-split:hover { transform: none; } } /* --- High-contrast: drop the glitter + orbs --------------- */ @media (prefers-contrast: more) { .scanlines, .y2k-orb-canvas { display: none; } }