Full Wave A build to the OVERRIDE-CONTRACT (frozen cms a0f07e2ae): - 49 mandatory builtin overrides in templates/overrides/magazine-bold/, re-skinned to streetwear cover-story chrome (massive condensed uppercase Archivo Black headlines, heavy 2px rules, hard square edges, mono datelines, fluoro accent slabs). Every content field, provider var, custom tag and JS block preserved verbatim from the frozen builtin defaults; legacy button (link/style/label) and card (media/text) field reads already reconciled. - 7 page templates: default, full-width, landing, article, blog-index, contact, auth. - 4 persona blocks (deleted masthead/photo_essay/pull_quote/issue_archive/ colophon — now overrides of navbar/gallery/quote/post-index/footer): cover_story, lookbook, drop_calendar, credits_ticker. - 5 dual-mode presets (newsprint+voltage light / ink-black+fluoro dark), all 19 tokens, dark tuned not inverted. - Bundled OFL woff2: Archivo Black (display), Inter (body), IBM Plex Mono (labels); fonts.json + assets/fonts/LICENSES.md. All font-family via var(--font-heading|body|mono, fallback). - Themed email-safe wrapper (tables, inline styles, streetwear defaults). - Master pages (navbar/footer/slot chrome) + seed demo site (OFFCUT label: home, about, blog + 3 posts, contact with data table + row_inserted → email-admins workflow, login) in fashion-label voice. - MID motion tier: marquee ticker, scroll reveal, duotone hover, scroll progress bar — all prefers-reduced-motion honored with static fallback, no canvas. - Icon packs (lucide, simple-icons) declared in plugin.mod + RECOMMENDED_ICONS. Verified: `make build` exit 0; `check-safety` 32 checks 19 ok 13 skip -> OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
457 lines
18 KiB
YAML
457 lines
18 KiB
YAML
# Magazine Bold theme — codeless .bnp manifest (Theme Fleet Wave A, WO-TF-021).
|
|
# Synthesized into manifest.pb by `ninja plugin build` (no plugin.wasm).
|
|
#
|
|
# Persona: a streetwear label / fashion-drop publication. Print-cover energy
|
|
# translated to drops and lookbooks — massive condensed uppercase headlines
|
|
# (Archivo Black), duotone imagery, grid-breaking overlap, mono datelines and
|
|
# fluoro accent slabs. Newsprint-plus-voltage by day, ink-black-plus-fluoro by
|
|
# night. Colour ALWAYS via hsl(var(--token)); font families ALWAYS via
|
|
# var(--font-heading|body|mono, <fallback>). No literal colours, no hardcoded
|
|
# families. Motion tier MID: JS effects (marquee, scroll reveal, duotone hover),
|
|
# no canvas, prefers-reduced-motion honored with static fallbacks.
|
|
theme_presets: presets.json
|
|
bundled_fonts: fonts.json
|
|
master_pages: master_pages.json
|
|
|
|
system_templates:
|
|
- key: magazine-bold
|
|
title: Magazine Bold
|
|
description: "A streetwear label's cover-story chrome: massive condensed uppercase headlines, duotone imagery, grid-breaking overlap and fluoro accent slabs. Built for fashion drops, lookbooks and culture publications."
|
|
|
|
page_templates:
|
|
- system: magazine-bold
|
|
key: default
|
|
title: Default
|
|
description: "Standard page: masthead, single reading column, colophon footer."
|
|
slots: [header, main, footer]
|
|
- system: magazine-bold
|
|
key: full-width
|
|
title: Full Bleed
|
|
description: "Edge-to-edge for lookbooks, cover images and photo essays."
|
|
slots: [header, main, footer]
|
|
- system: magazine-bold
|
|
key: landing
|
|
title: Cover / Drop
|
|
description: "Cover-story stack: masthead, lead drop, river of stories, colophon."
|
|
slots: [masthead, lead, river, footer]
|
|
- system: magazine-bold
|
|
key: article
|
|
title: Feature
|
|
description: "Long-form feature: byline, drop-cap opener, reading column with a marginalia rail."
|
|
slots: [header, byline, main, marginalia, footer]
|
|
- system: magazine-bold
|
|
key: blog-index
|
|
title: Archive
|
|
description: "Drop archive: masthead, featured drop, and a river of stories."
|
|
slots: [header, featured, main, footer]
|
|
- system: magazine-bold
|
|
key: contact
|
|
title: Studio
|
|
description: "Contact layout with an optional aside for stockists, hours and location."
|
|
slots: [header, main, aside, footer]
|
|
- system: magazine-bold
|
|
key: auth
|
|
title: Members
|
|
description: "Centred members shell with wordmark and a fluoro rule."
|
|
slots: [main, footer]
|
|
|
|
template_overrides:
|
|
# Chrome (4)
|
|
- { template: magazine-bold, block: navbar }
|
|
- { template: magazine-bold, block: footer }
|
|
- { template: magazine-bold, block: utility-bar }
|
|
- { template: magazine-bold, block: announcement-bar }
|
|
# Marketing (12)
|
|
- { template: magazine-bold, block: hero }
|
|
- { template: magazine-bold, block: feature-grid }
|
|
- { template: magazine-bold, block: rich-section }
|
|
- { template: magazine-bold, block: stats }
|
|
- { template: magazine-bold, block: testimonial }
|
|
- { template: magazine-bold, block: logo-strip }
|
|
- { template: magazine-bold, block: pricing }
|
|
- { template: magazine-bold, block: team }
|
|
- { template: magazine-bold, block: faq }
|
|
- { template: magazine-bold, block: timeline }
|
|
- { template: magazine-bold, block: cta }
|
|
- { template: magazine-bold, block: countdown }
|
|
# Primitives (11)
|
|
- { template: magazine-bold, block: heading }
|
|
- { template: magazine-bold, block: text }
|
|
- { template: magazine-bold, block: rich-text }
|
|
- { template: magazine-bold, block: image }
|
|
- { template: magazine-bold, block: quote }
|
|
- { template: magazine-bold, block: divider }
|
|
- { template: magazine-bold, block: button }
|
|
- { template: magazine-bold, block: card }
|
|
- { template: magazine-bold, block: gallery }
|
|
- { template: magazine-bold, block: video-embed }
|
|
- { template: magazine-bold, block: audio-embed }
|
|
# Commerce / local (6)
|
|
- { template: magazine-bold, block: menu-list }
|
|
- { template: magazine-bold, block: event-list }
|
|
- { template: magazine-bold, block: contact-form }
|
|
- { template: magazine-bold, block: contact-card }
|
|
- { template: magazine-bold, block: hours-location }
|
|
- { template: magazine-bold, block: social-links }
|
|
# Blog family (12)
|
|
- { template: magazine-bold, block: blog-hero }
|
|
- { template: magazine-bold, block: featured-posts }
|
|
- { template: magazine-bold, block: related-posts }
|
|
- { template: magazine-bold, block: popular-posts }
|
|
- { template: magazine-bold, block: category-list }
|
|
- { template: magazine-bold, block: post-hero }
|
|
- { template: magazine-bold, block: post-metadata }
|
|
- { template: magazine-bold, block: author-bio }
|
|
- { template: magazine-bold, block: author-bio-hero }
|
|
- { template: magazine-bold, block: newsletter-signup }
|
|
- { template: magazine-bold, block: breadcrumbs }
|
|
- { template: magazine-bold, block: sidebar-nav }
|
|
# Auth surface (3)
|
|
- { template: magazine-bold, block: auth-form }
|
|
- { template: magazine-bold, block: password-reset-form }
|
|
- { template: magazine-bold, block: auth-status }
|
|
# System (1)
|
|
- { template: magazine-bold, block: page-suggestions }
|
|
|
|
email_wrappers:
|
|
- magazine-bold
|
|
|
|
css:
|
|
input_css_append: |
|
|
/* === Magazine Bold theme — utility layer ===
|
|
*
|
|
* Streetwear / fashion-drop identity: massive condensed uppercase headlines,
|
|
* heavy 2px rules, hard square edges, mono datelines and fluoro accent slabs.
|
|
* Colour is ALWAYS consumed via hsl(var(--token)); font families ALWAYS via
|
|
* var(--font-heading|body|mono, <fallback>). No literal colours, no hardcoded
|
|
* families.
|
|
*/
|
|
|
|
@layer utilities {
|
|
:root {
|
|
--mb-measure: 68ch;
|
|
--mb-rule: 2px solid hsl(var(--foreground));
|
|
}
|
|
|
|
/* --- Font slots (consume CMS-managed font variables) --- */
|
|
.font-display { font-family: var(--font-heading, "Archivo Black", "Arial Black", sans-serif); }
|
|
.font-sans { font-family: var(--font-body, "Inter", system-ui, sans-serif); }
|
|
.font-mono { font-family: var(--font-mono, "IBM Plex Mono", ui-monospace, monospace); }
|
|
|
|
/* --- Page widths / reading measures --- */
|
|
.mb-column {
|
|
max-width: var(--mb-measure);
|
|
margin-left: auto; margin-right: auto;
|
|
padding-left: 1rem; padding-right: 1rem;
|
|
}
|
|
.mb-wide {
|
|
max-width: 80rem;
|
|
margin-left: auto; margin-right: auto;
|
|
padding-left: 1rem; padding-right: 1rem;
|
|
}
|
|
.mb-article-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
gap: 2rem;
|
|
max-width: 84rem;
|
|
margin-left: auto; margin-right: auto;
|
|
padding-left: 1rem; padding-right: 1rem;
|
|
}
|
|
@media (min-width: 1024px) {
|
|
.mb-article-grid { grid-template-columns: minmax(0, 68ch) 18rem; }
|
|
}
|
|
|
|
/* --- Prose reading column --- */
|
|
.mb-prose {
|
|
max-width: var(--mb-measure);
|
|
margin-left: auto; margin-right: auto;
|
|
font-family: var(--font-body, "Inter", system-ui, sans-serif);
|
|
color: hsl(var(--foreground));
|
|
line-height: 1.6;
|
|
}
|
|
.mb-prose p { margin: 0 0 1.15em 0; }
|
|
.mb-prose h1, .mb-prose h2, .mb-prose h3, .mb-prose h4 {
|
|
font-family: var(--font-heading, "Archivo Black", "Arial Black", sans-serif);
|
|
text-transform: uppercase;
|
|
letter-spacing: -0.01em;
|
|
line-height: 1.0;
|
|
color: hsl(var(--foreground));
|
|
}
|
|
.mb-prose a {
|
|
color: hsl(var(--accent));
|
|
text-decoration: underline;
|
|
text-decoration-thickness: 2px;
|
|
text-underline-offset: 2px;
|
|
}
|
|
.mb-prose blockquote {
|
|
font-weight: 500;
|
|
border-left: 4px solid hsl(var(--accent));
|
|
padding-left: 1rem; margin-left: 0;
|
|
color: hsl(var(--foreground));
|
|
}
|
|
|
|
/* --- Mono / tracked labels (kickers, eyebrows, meta) --- */
|
|
.mb-caps {
|
|
font-family: var(--font-mono, "IBM Plex Mono", ui-monospace, monospace);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.14em;
|
|
font-weight: 500;
|
|
font-size: 0.72rem;
|
|
line-height: 1.35;
|
|
}
|
|
|
|
/* --- Display heading (Archivo Black, massive condensed caps) --- */
|
|
.mb-heading {
|
|
font-family: var(--font-heading, "Archivo Black", "Arial Black", sans-serif);
|
|
text-transform: uppercase;
|
|
letter-spacing: -0.02em;
|
|
line-height: 0.95;
|
|
color: hsl(var(--foreground));
|
|
}
|
|
.mb-underline { position: relative; padding-bottom: 0.28em; }
|
|
.mb-underline::after {
|
|
content: "";
|
|
position: absolute; left: 0; right: 0; bottom: 0;
|
|
height: 4px;
|
|
background: hsl(var(--accent));
|
|
}
|
|
|
|
/* --- Heavy rules (bars, not hairlines) --- */
|
|
hr.mb-rule, .mb-rule, .mb-hairline {
|
|
border: 0;
|
|
border-top: var(--mb-rule);
|
|
margin: 0;
|
|
}
|
|
.mb-hairline-top { border-top: var(--mb-rule); }
|
|
.mb-hairline-bottom { border-bottom: var(--mb-rule); }
|
|
|
|
/* --- Body text override --- */
|
|
.mb-body {
|
|
font-family: var(--font-body, "Inter", system-ui, sans-serif);
|
|
color: hsl(var(--foreground));
|
|
line-height: 1.6;
|
|
}
|
|
|
|
/* --- Inline accent link --- */
|
|
.mb-link {
|
|
color: hsl(var(--accent));
|
|
text-decoration: underline;
|
|
text-decoration-thickness: 2px;
|
|
text-underline-offset: 3px;
|
|
transition: color 120ms ease, text-decoration-color 120ms ease;
|
|
}
|
|
.mb-link:hover, .mb-link:focus-visible { color: hsl(var(--foreground)); }
|
|
|
|
/* --- Button — fluoro / ink slab, square, uppercase mono --- */
|
|
.mb-button, .mb-btn {
|
|
display: inline-block;
|
|
padding: 0.7rem 1.4rem;
|
|
font-family: var(--font-mono, "IBM Plex Mono", ui-monospace, monospace);
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.14em;
|
|
background-color: hsl(var(--foreground));
|
|
color: hsl(var(--background));
|
|
border: 2px solid hsl(var(--foreground));
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
|
|
}
|
|
.mb-button:hover, .mb-button:focus, .mb-btn:hover, .mb-btn:focus {
|
|
background-color: hsl(var(--accent));
|
|
color: hsl(var(--accent-foreground));
|
|
border-color: hsl(var(--accent));
|
|
}
|
|
.mb-button:focus-visible, .mb-btn:focus-visible {
|
|
outline: 2px solid hsl(var(--ring));
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* --- Panel / card — heavy 2px frame, hard edges, no shadow --- */
|
|
.mb-panel, .mb-card {
|
|
border: 2px solid hsl(var(--foreground));
|
|
background-color: hsl(var(--card));
|
|
transition: border-color 120ms ease, transform 120ms ease;
|
|
}
|
|
.mb-panel:hover, .mb-card:hover { border-color: hsl(var(--accent)); }
|
|
|
|
/* --- Form field — heavy border, square, accent focus --- */
|
|
.mb-input {
|
|
width: 100%;
|
|
border: 2px solid hsl(var(--input));
|
|
background-color: hsl(var(--background));
|
|
color: hsl(var(--foreground));
|
|
padding: 0.6rem 0.8rem;
|
|
font-family: var(--font-body, "Inter", system-ui, sans-serif);
|
|
font-size: 0.95rem;
|
|
border-radius: 0;
|
|
}
|
|
.mb-input::placeholder { color: hsl(var(--muted-foreground)); }
|
|
.mb-input:focus {
|
|
outline: none;
|
|
border-color: hsl(var(--accent));
|
|
box-shadow: 0 0 0 2px hsl(var(--accent));
|
|
}
|
|
|
|
/* --- Figure / caption --- */
|
|
.mb-figure { margin: 1.5rem 0; }
|
|
.mb-figure img { display: block; width: 100%; height: auto; }
|
|
.mb-figure figcaption {
|
|
margin-top: 0.6rem;
|
|
font-family: var(--font-mono, "IBM Plex Mono", ui-monospace, monospace);
|
|
font-size: 0.72rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
color: hsl(var(--muted-foreground));
|
|
}
|
|
.mb-caption {
|
|
font-family: var(--font-mono, "IBM Plex Mono", ui-monospace, monospace);
|
|
font-size: 0.72rem;
|
|
line-height: 1.4;
|
|
letter-spacing: 0.04em;
|
|
color: hsl(var(--muted-foreground));
|
|
}
|
|
|
|
/* --- Drop cap — oversized Archivo Black accent first letter --- */
|
|
.mb-dropcap p:first-of-type::first-letter {
|
|
font-family: var(--font-heading, "Archivo Black", "Arial Black", sans-serif);
|
|
color: hsl(var(--accent));
|
|
float: left;
|
|
font-size: 4.6em;
|
|
line-height: 0.78;
|
|
padding-right: 0.1em;
|
|
padding-top: 0.02em;
|
|
margin-bottom: -0.08em;
|
|
}
|
|
|
|
/* --- Marginalia rail (mono side notes, MID motion reveal) --- */
|
|
.mb-marginalia {
|
|
font-family: var(--font-mono, "IBM Plex Mono", ui-monospace, monospace);
|
|
font-size: 0.75rem;
|
|
line-height: 1.5;
|
|
color: hsl(var(--muted-foreground));
|
|
}
|
|
.mb-marginalia aside {
|
|
margin: 0 0 1.5rem 0;
|
|
padding-left: 0.75rem;
|
|
border-left: var(--mb-rule);
|
|
opacity: 0;
|
|
animation: mb-fade-in 500ms ease forwards;
|
|
}
|
|
@keyframes mb-fade-in { to { opacity: 1; } }
|
|
@media (max-width: 768px) {
|
|
.mb-marginalia {
|
|
margin-top: 1.5rem;
|
|
border-top: var(--mb-rule);
|
|
padding-top: 1rem;
|
|
}
|
|
}
|
|
|
|
/* --- Masthead wordmark --- */
|
|
.mb-masthead-wordmark {
|
|
font-family: var(--font-heading, "Archivo Black", "Arial Black", sans-serif);
|
|
text-transform: uppercase;
|
|
letter-spacing: -0.03em;
|
|
color: hsl(var(--foreground));
|
|
}
|
|
|
|
/* --- Display size utilities (folio / deck / kicker) --- */
|
|
.text-folio {
|
|
font-family: var(--font-heading, "Archivo Black", "Arial Black", sans-serif);
|
|
font-size: clamp(72px, 16vw, 220px);
|
|
line-height: 0.82;
|
|
letter-spacing: -0.04em;
|
|
text-transform: uppercase;
|
|
}
|
|
.text-deck {
|
|
font-family: var(--font-body, "Inter", system-ui, sans-serif);
|
|
font-size: clamp(24px, 3vw, 44px);
|
|
line-height: 1.12;
|
|
letter-spacing: -0.01em;
|
|
font-weight: 500;
|
|
}
|
|
.text-kicker {
|
|
font-family: var(--font-mono, "IBM Plex Mono", ui-monospace, monospace);
|
|
font-size: 12px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.18em;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* --- Asymmetric editorial grids (persona blocks) --- */
|
|
.mb-grid-12 { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 1.5rem; }
|
|
.mb-photo-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 1.25rem; }
|
|
.mb-frame-half { grid-column: span 6 / span 6; }
|
|
.mb-frame-full { grid-column: 1 / -1; }
|
|
.mb-frame-tall { grid-column: span 5 / span 5; grid-row: span 2; }
|
|
@media (max-width: 768px) {
|
|
.mb-photo-grid { grid-template-columns: 1fr; }
|
|
.mb-frame-half, .mb-frame-full, .mb-frame-tall { grid-column: 1 / -1; grid-row: auto; }
|
|
}
|
|
|
|
/* --- Color-block accent panel --- */
|
|
.colorblock-accent { background-color: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
|
|
|
|
/* --- Full-bleed image --- */
|
|
.mb-fullbleed { width: 100vw; max-width: 100vw; margin-left: 50%; transform: translateX(-50%); }
|
|
|
|
/* --- Duotone photo treatment (signature — persona blocks) --- */
|
|
.mb-duotone { position: relative; }
|
|
.mb-duotone img { filter: grayscale(1) contrast(1.15); display: block; width: 100%; height: 100%; object-fit: cover; }
|
|
.mb-duotone::after {
|
|
content: ""; position: absolute; inset: 0;
|
|
background: hsl(var(--accent));
|
|
mix-blend-mode: multiply;
|
|
opacity: 0.55;
|
|
transition: opacity 200ms ease;
|
|
pointer-events: none;
|
|
}
|
|
.mb-duotone:hover::after { opacity: 0.2; }
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.mb-duotone:hover::after { opacity: 0.55; }
|
|
}
|
|
|
|
/* --- Scroll reveal (MID motion; static fallback) --- */
|
|
.mb-reveal { opacity: 0; transform: translateY(16px); transition: opacity 500ms ease, transform 500ms ease; }
|
|
.mb-reveal.mb-in { opacity: 1; transform: none; }
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.mb-reveal { opacity: 1; transform: none; transition: none; }
|
|
}
|
|
.no-js .mb-reveal { opacity: 1; transform: none; }
|
|
|
|
/* --- Marquee ticker (MID motion; paused on hover; static fallback) --- */
|
|
.mb-marquee { overflow: hidden; white-space: nowrap; }
|
|
.mb-marquee-track {
|
|
display: inline-block;
|
|
will-change: transform;
|
|
animation: mb-marquee 22s linear infinite;
|
|
}
|
|
.mb-marquee:hover .mb-marquee-track { animation-play-state: paused; }
|
|
@keyframes mb-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.mb-marquee-track { animation: none; }
|
|
}
|
|
|
|
/* --- Reading-progress bar (fluoro; scroll-timeline; reduced-motion guard) --- */
|
|
.mb-progress {
|
|
position: sticky; top: 0;
|
|
height: 4px;
|
|
background: hsl(var(--accent));
|
|
transform-origin: 0 50%;
|
|
animation: mb-progress linear both;
|
|
animation-timeline: scroll(root block);
|
|
z-index: 50;
|
|
}
|
|
@keyframes mb-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.mb-progress { animation: none; transform: scaleX(0); }
|
|
}
|
|
|
|
/* --- Per-instance pull-quote accent override (persona quote) --- */
|
|
[data-mb-accent="pink"] { --mb-accent-h: 330; --mb-accent-s: 95%; --mb-accent-l: 58%; }
|
|
[data-mb-accent="blue"] { --mb-accent-h: 220; --mb-accent-s: 100%; --mb-accent-l: 56%; }
|
|
[data-mb-accent="lime"] { --mb-accent-h: 78; --mb-accent-s: 90%; --mb-accent-l: 50%; }
|
|
[data-mb-accent] .mb-quote-bar { background-color: hsl(var(--mb-accent-h) var(--mb-accent-s) var(--mb-accent-l)); }
|
|
}
|