# 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; /* Subtle chrome bevel only — the old wide primary halo read as a stray rendering artifact behind every heading, so it is gone. */ text-shadow: 0 1px 0 hsl(var(--bevel-light) / 0.55), 0 1px 1px hsl(var(--bevel-dark) / 0.22); } /* Chrome shimmer sweep across big headlines (motion, reduced-motion-safe). Toned to a faint glint so it never smears the letters in a still frame. */ .glitch { position: relative; background-image: linear-gradient( 100deg, transparent 35%, hsl(var(--bevel-light) / 0.3) 48%, hsl(var(--accent) / 0.22) 50%, transparent 62%); 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); } /* --- Responsive persona grids ----------------------------- */ /* Explicit media queries so column counts do NOT depend on the host Tailwind build having scanned these theme templates (persona blocks use responsive class combos no builtin emits, so the JIT drops them and the grid collapses to its base count). 1 col on phones. */ .y2k-grid-records { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1fr); } @media (min-width: 640px) { .y2k-grid-records { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (min-width: 1024px) { .y2k-grid-records { grid-template-columns: repeat(4, minmax(0, 1fr)); } } /* Compact chrome tile for absent album/track art — a fixed, modest height so an empty media field never balloons into a blank box. */ .y2k-media-empty { display: flex; align-items: center; justify-content: center; height: 11rem; } /* --- 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; } }