WO-TF-015 (game-studio / hacker-collective persona, GO-BIG motion). - Overrides: all 49 mandatory builtin keys in templates/overrides/cyberpunk/ (dashed keys), each restyled to neon-HUD chrome preserving builtin field reads + scripts. Legacy button/card/heading/text reconciled to new field names (label/link/style, text/media). Auth surface (auth-form, auth-status, password-reset-form) reproduces the builtin hardcoded HTMX endpoints + Cap widget verbatim. page-suggestions ships themed 404 chrome. - Page templates: 7 (default, full-width, landing, article, blog-index, contact, auth), dual-mode via theme_mode, scanline overlay chrome. - Hero override: dependency-free canvas digital-rain showpiece — lazy-init via IntersectionObserver, prefers-reduced-motion honored, static neon gradient no-JS fallback, token-derived colors only. - Blocks: deleted 6 builtin-duplicating theme blocks (now overrides); kept code_neon (+ copy handler); added persona blocks glitch_hero, roster_grid, patch_notes with schemas + sample data. - Presets: 5 (neon-noir, acid-rain, toxic-bloom, hotline, ghost-protocol), all 19 tokens, light+dark both tuned. - Fonts: bundled OFL woff2 (Orbitron, Share Tech Mono, Inter latin subsets) in assets/fonts + fonts.json + LICENSES; all font-family via CSS vars. - Email: preset-aware email-safe wrapper (tables, inline styles, colors.*). - Master pages + demo seed (home, about, blog+3 posts, contact with data-table + row_inserted email-admins workflow, login). - manifest CSS: hud-frame, clip-cut, cyberpunk-eyebrow, canvas-rain utils. - plugin.mod + manifest required_icon_packs = [lucide, simple-icons]. make build + verify exit 0; check-safety exit 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
378 lines
13 KiB
YAML
378 lines
13 KiB
YAML
# Cyberpunk theme — codeless .bnp manifest (WO-TF-015, Wave A).
|
|
# Synthesized into manifest.pb by `ninja plugin build` (no plugin.wasm).
|
|
theme_presets: presets.json
|
|
bundled_fonts: fonts.json
|
|
master_pages: master_pages.json
|
|
required_icon_packs: ["lucide", "simple-icons"]
|
|
|
|
system_templates:
|
|
- key: cyberpunk
|
|
title: Cyberpunk
|
|
description: "Neon-on-black game-studio / hacker-collective theme — RGB-split glitch, CRT scanlines, HUD brackets, angled clip cuts, and a canvas digital-rain hero."
|
|
|
|
page_templates:
|
|
- system: cyberpunk
|
|
key: default
|
|
title: Default
|
|
description: "Standard dark page with scanline overlay and a sticky terminal-style header"
|
|
slots: [header, main, footer]
|
|
- system: cyberpunk
|
|
key: full-width
|
|
title: Full Width
|
|
description: "Edge-to-edge dashboard / showcase layout, no max-width"
|
|
slots: [header, main, footer]
|
|
- system: cyberpunk
|
|
key: landing
|
|
title: Landing
|
|
description: "Canvas digital-rain hero, neon feature grid, glowing CTA, footer"
|
|
slots: [header, main, footer]
|
|
- system: cyberpunk
|
|
key: article
|
|
title: Article
|
|
description: "Mono-metadata header, prose column, HUD-framed aside"
|
|
slots: [header, main, aside, footer]
|
|
- system: cyberpunk
|
|
key: blog-index
|
|
title: Blog Index
|
|
description: "Patch-notes feed layout with neon post cards and sidebar"
|
|
slots: [header, main, footer]
|
|
- system: cyberpunk
|
|
key: contact
|
|
title: Contact
|
|
description: "Terminal contact console — form panel plus HUD contact card"
|
|
slots: [header, main, footer]
|
|
- system: cyberpunk
|
|
key: auth
|
|
title: Auth
|
|
description: "Centered neon auth console for login / register / reset"
|
|
slots: [header, main, footer]
|
|
|
|
# All 49 mandatory-tier builtin overrides (OVERRIDE-CONTRACT §1), dashed keys.
|
|
template_overrides:
|
|
# Chrome (4)
|
|
- { template: cyberpunk, block: navbar }
|
|
- { template: cyberpunk, block: footer }
|
|
- { template: cyberpunk, block: utility-bar }
|
|
- { template: cyberpunk, block: announcement-bar }
|
|
# Marketing (12)
|
|
- { template: cyberpunk, block: hero }
|
|
- { template: cyberpunk, block: feature-grid }
|
|
- { template: cyberpunk, block: rich-section }
|
|
- { template: cyberpunk, block: stats }
|
|
- { template: cyberpunk, block: testimonial }
|
|
- { template: cyberpunk, block: logo-strip }
|
|
- { template: cyberpunk, block: pricing }
|
|
- { template: cyberpunk, block: team }
|
|
- { template: cyberpunk, block: faq }
|
|
- { template: cyberpunk, block: timeline }
|
|
- { template: cyberpunk, block: cta }
|
|
- { template: cyberpunk, block: countdown }
|
|
# Primitives (11)
|
|
- { template: cyberpunk, block: heading }
|
|
- { template: cyberpunk, block: text }
|
|
- { template: cyberpunk, block: rich-text }
|
|
- { template: cyberpunk, block: image }
|
|
- { template: cyberpunk, block: quote }
|
|
- { template: cyberpunk, block: divider }
|
|
- { template: cyberpunk, block: button }
|
|
- { template: cyberpunk, block: card }
|
|
- { template: cyberpunk, block: gallery }
|
|
- { template: cyberpunk, block: video-embed }
|
|
- { template: cyberpunk, block: audio-embed }
|
|
# Commerce / local (6)
|
|
- { template: cyberpunk, block: menu-list }
|
|
- { template: cyberpunk, block: event-list }
|
|
- { template: cyberpunk, block: contact-form }
|
|
- { template: cyberpunk, block: contact-card }
|
|
- { template: cyberpunk, block: hours-location }
|
|
- { template: cyberpunk, block: social-links }
|
|
# Blog family (12)
|
|
- { template: cyberpunk, block: blog-hero }
|
|
- { template: cyberpunk, block: featured-posts }
|
|
- { template: cyberpunk, block: related-posts }
|
|
- { template: cyberpunk, block: popular-posts }
|
|
- { template: cyberpunk, block: category-list }
|
|
- { template: cyberpunk, block: post-hero }
|
|
- { template: cyberpunk, block: post-metadata }
|
|
- { template: cyberpunk, block: author-bio }
|
|
- { template: cyberpunk, block: author-bio-hero }
|
|
- { template: cyberpunk, block: newsletter-signup }
|
|
- { template: cyberpunk, block: breadcrumbs }
|
|
- { template: cyberpunk, block: sidebar-nav }
|
|
# Auth surface (3)
|
|
- { template: cyberpunk, block: auth-form }
|
|
- { template: cyberpunk, block: password-reset-form }
|
|
- { template: cyberpunk, block: auth-status }
|
|
# System (1)
|
|
- { template: cyberpunk, block: page-suggestions }
|
|
|
|
email_wrappers:
|
|
- cyberpunk
|
|
|
|
css:
|
|
input_css_append: |
|
|
/* ============================================================
|
|
Cyberpunk — Neon-on-black game-studio / hacker-collective theme
|
|
(WO-TF-015). Scanlines / glitch / RGB-split / caret-blink /
|
|
neon-edge / HUD-bracket / clip-cut / digital-rain utilities.
|
|
All colours consume the host shadcn HSL tokens via hsl(var(--token)).
|
|
No hardcoded hex / rgb / named colours.
|
|
============================================================ */
|
|
|
|
/* --- 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). */
|
|
|
|
.cyberpunk-body {
|
|
font-family: var(--font-body, "Inter", system-ui, -apple-system, "Segoe UI", sans-serif);
|
|
}
|
|
|
|
.cyberpunk-mono,
|
|
.cyberpunk-mono code,
|
|
pre.cyberpunk-mono,
|
|
code.cyberpunk-mono {
|
|
font-family: var(--font-mono, "Share Tech Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, monospace);
|
|
}
|
|
|
|
.cyberpunk-display {
|
|
font-family: var(--font-heading, "Orbitron", system-ui, -apple-system, "Segoe UI", sans-serif);
|
|
letter-spacing: 0.01em;
|
|
}
|
|
|
|
.cyberpunk-prose,
|
|
.cyberpunk-prose p,
|
|
.cyberpunk-prose li {
|
|
font-family: var(--font-body, "Inter", system-ui, sans-serif);
|
|
line-height: 1.75;
|
|
}
|
|
|
|
/* Eyebrow / kicker: mono, uppercase, wide-tracked accent readout. Carries
|
|
enough on its own that it is never a silent no-op when used alone. */
|
|
.cyberpunk-eyebrow {
|
|
font-family: var(--font-mono, "Share Tech Mono", ui-monospace, monospace);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.2em;
|
|
font-size: 0.75rem;
|
|
color: hsl(var(--accent));
|
|
}
|
|
|
|
.cyberpunk-prose code {
|
|
color: hsl(var(--accent));
|
|
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;
|
|
}
|
|
|
|
/* --- Scanlines -------------------------------------------- */
|
|
|
|
.scanlines {
|
|
opacity: 0.05;
|
|
background-image: linear-gradient(
|
|
to bottom,
|
|
hsl(var(--foreground)) 0px,
|
|
hsl(var(--foreground)) 1px,
|
|
transparent 1px,
|
|
transparent 3px
|
|
);
|
|
background-size: 100% 3px;
|
|
animation: scanline-drift 6s linear infinite;
|
|
}
|
|
|
|
@keyframes scanline-drift {
|
|
0% { background-position: 0 0; }
|
|
100% { background-position: 0 3px; }
|
|
}
|
|
|
|
/* --- Glitch (RGB-split text-shadow) on big headings ------- */
|
|
|
|
.glitch {
|
|
position: relative;
|
|
text-shadow:
|
|
-2px 0 hsl(var(--primary)),
|
|
2px 0 hsl(var(--accent));
|
|
animation: glitch-x 3.6s steps(1, end) infinite;
|
|
}
|
|
|
|
@keyframes glitch-x {
|
|
0%, 92%, 100% {
|
|
text-shadow: -2px 0 hsl(var(--primary)), 2px 0 hsl(var(--accent));
|
|
}
|
|
93% {
|
|
text-shadow: -3px 0 hsl(var(--primary)), 3px 0 hsl(var(--accent)), 0 1px hsl(var(--accent));
|
|
}
|
|
95% {
|
|
text-shadow: -1px 0 hsl(var(--accent)), 4px 0 hsl(var(--primary));
|
|
}
|
|
97% {
|
|
text-shadow: -2px 0 hsl(var(--primary)), 2px 0 hsl(var(--accent));
|
|
}
|
|
}
|
|
|
|
/* --- RGB-split hover/focus/active on primary buttons ------ */
|
|
|
|
.rgb-split {
|
|
transition: transform 120ms ease, box-shadow 120ms ease;
|
|
}
|
|
.rgb-split:hover,
|
|
.rgb-split:focus-visible {
|
|
box-shadow: -2px 0 0 hsl(var(--primary)), 2px 0 0 hsl(var(--accent));
|
|
transform: translateY(-1px);
|
|
}
|
|
.cyberpunk-btn:active,
|
|
.rgb-split:active,
|
|
button.cyberpunk-btn:active {
|
|
box-shadow: -2px 0 0 hsl(var(--primary)), 2px 0 0 hsl(var(--accent));
|
|
}
|
|
.cyberpunk-btn:focus-visible,
|
|
.cyberpunk-btn-ghost:focus-visible,
|
|
button:focus-visible,
|
|
a:focus-visible {
|
|
outline: 2px solid hsl(var(--ring));
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* --- Caret blink ------------------------------------------ */
|
|
|
|
.caret-blink {
|
|
display: inline-block;
|
|
animation: caret 1.05s steps(2, end) infinite;
|
|
}
|
|
@keyframes caret {
|
|
0%, 50% { opacity: 1; }
|
|
51%, 100% { opacity: 0; }
|
|
}
|
|
|
|
/* --- Neon edge utilities (magenta / cyan / lime channels) - */
|
|
/* --primary is the lead accent, --accent the secondary, --ring
|
|
the third neon channel (present in every preset). */
|
|
|
|
.neon-edge-magenta {
|
|
box-shadow: 0 0 0 1px hsl(var(--primary) / 0.4), 0 0 18px hsl(var(--primary) / 0.22);
|
|
transition: box-shadow 180ms ease, transform 180ms ease;
|
|
}
|
|
.neon-edge-magenta:hover,
|
|
.neon-edge-magenta:focus-within {
|
|
box-shadow: 0 0 0 1px hsl(var(--primary) / 0.85), 0 0 28px hsl(var(--primary) / 0.42);
|
|
transform: translateY(-1px);
|
|
}
|
|
.neon-edge-cyan {
|
|
box-shadow: 0 0 0 1px hsl(var(--accent) / 0.4), 0 0 18px hsl(var(--accent) / 0.22);
|
|
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 28px hsl(var(--accent) / 0.42);
|
|
transform: translateY(-1px);
|
|
}
|
|
.neon-edge-lime {
|
|
box-shadow: 0 0 0 1px hsl(var(--ring) / 0.4), 0 0 18px hsl(var(--ring) / 0.22);
|
|
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 28px hsl(var(--ring) / 0.42);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
/* --- HUD corner brackets ---------------------------------- */
|
|
/* Draw two L-brackets (top-left, bottom-right) around any panel. */
|
|
|
|
.hud-frame {
|
|
position: relative;
|
|
}
|
|
.hud-frame::before,
|
|
.hud-frame::after {
|
|
content: "";
|
|
position: absolute;
|
|
width: 14px;
|
|
height: 14px;
|
|
pointer-events: none;
|
|
z-index: 1;
|
|
}
|
|
.hud-frame::before {
|
|
top: -1px;
|
|
left: -1px;
|
|
border-top: 2px solid hsl(var(--primary));
|
|
border-left: 2px solid hsl(var(--primary));
|
|
}
|
|
.hud-frame::after {
|
|
bottom: -1px;
|
|
right: -1px;
|
|
border-bottom: 2px solid hsl(var(--accent));
|
|
border-right: 2px solid hsl(var(--accent));
|
|
}
|
|
|
|
/* --- Angled clip-path cut (arcade panel silhouette) ------- */
|
|
|
|
.clip-cut {
|
|
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 10px 100%, 0 calc(100% - 10px));
|
|
}
|
|
|
|
/* --- Status pill / dot pulse ------------------------------ */
|
|
|
|
.cyberpunk-status-dot {
|
|
animation: cyberpunk-pulse 2.2s ease-in-out infinite;
|
|
}
|
|
@keyframes cyberpunk-pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.4; }
|
|
}
|
|
|
|
/* --- Digital-rain canvas showpiece (hero override only) --- */
|
|
/* The <canvas> lazy-inits from the hero's inline script. This block
|
|
styles the container + the static no-JS neon fallback layer. */
|
|
|
|
.cyberpunk-rain-wrap {
|
|
position: absolute;
|
|
inset: 0;
|
|
overflow: hidden;
|
|
pointer-events: none;
|
|
}
|
|
.cyberpunk-rain-canvas {
|
|
position: absolute;
|
|
inset: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: block;
|
|
opacity: 0.5;
|
|
}
|
|
/* Static fallback: a neon vertical-gradient wash shown until (or instead
|
|
of) the canvas. Tokens only. */
|
|
.cyberpunk-rain-fallback {
|
|
position: absolute;
|
|
inset: 0;
|
|
background:
|
|
radial-gradient(120% 80% at 50% 0%, hsl(var(--primary) / 0.18), transparent 60%),
|
|
radial-gradient(120% 80% at 100% 100%, hsl(var(--accent) / 0.16), transparent 55%),
|
|
linear-gradient(to bottom, transparent, hsl(var(--background) / 0.6));
|
|
}
|
|
|
|
/* --- Reduced motion: kill all motion --------------------- */
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.glitch,
|
|
.caret-blink,
|
|
.scanlines,
|
|
.cyberpunk-status-dot,
|
|
.cyberpunk-rain-canvas {
|
|
animation: none !important;
|
|
animation-duration: 0.01ms !important;
|
|
}
|
|
.glitch { text-shadow: none; }
|
|
.scanlines { opacity: 0; }
|
|
.cyberpunk-rain-canvas { display: none; }
|
|
.rgb-split:hover,
|
|
.rgb-split:focus-visible { transform: none; }
|
|
}
|
|
|
|
/* --- High-contrast: kill scanlines + rain ---------------- */
|
|
|
|
@media (prefers-contrast: more) {
|
|
.scanlines,
|
|
.cyberpunk-rain-canvas { display: none; }
|
|
}
|